varstor 0.6.62 → 0.6.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -25,8 +25,9 @@ in your script file.
25
25
  [1.3 Accessing ```.get()```](#accessing)
26
26
  [1.4 Mutating ```.set()```/```.reset()```](#mutating)
27
27
  [1.5 Listening ```.onChange()```/```.removeListener()```](#listening)
28
- [1.6 Namespacing ```.get(Namespace)```](#namespacing)
29
- [1.7 Method chaining](#chaining)
28
+ [1.6 Data encapsulation ```.actions()```](#actions)
29
+ [1.7 Namespacing ```.get(Namespace)```](#namespacing)
30
+ [1.8 Method chaining](#chaining)
30
31
  2. [Shortcuts](#shortcuts)
31
32
  3. [Example](#example)
32
33
 
@@ -40,6 +41,7 @@ The library object features the following methods:
40
41
  .reset ()
41
42
  .onChange ()
42
43
  .removeListener ()
44
+ .actions ()
43
45
  ```
44
46
 
45
47
  ## Creation ```.add()```/```.addPersistent()``` <a name="creation"></a>
@@ -128,6 +130,31 @@ Varstor.removeListener(
128
130
  ) => Varstor
129
131
  ```
130
132
  the same parameter usage.
133
+
134
+
135
+
136
+ ## Data encapsulation ```.actions()``` <a name="actions"></a>
137
+ Hide away all public data access and mutation into dedicated functions with the help of ```IStateAction```s.
138
+ ```js
139
+ Varstor.actions({
140
+ KeysActions {
141
+ key1: IStateAction1 (Varstor, ...arguments[]) => void
142
+ key2: IStateAction2 (Varstor, ...arguments[]) => void
143
+ ...
144
+ }
145
+ })
146
+ ```
147
+ ```IStateAction``` function type binds ```Varstor``` instance as the first argument, followed by all other ```arguments``` provided by the user at the time of the call.
148
+ These actions reside in the same scope as regular variables. So you can access them by the ```key```s defined in ```KeysActions``` object through the ```.get()``` method.
149
+ ```js
150
+ Varstor.add({ x: 1 });
151
+
152
+ Varstor.actions({
153
+ changeX: (varstor, newX) => varstor.set({ x: newX }),
154
+ }),
155
+
156
+ Varstor.get().changeX(10);
157
+ ```
131
158
 
132
159
  ## Namespacing ```.get(Namespace)``` <a name="namespacing"></a>
133
160
  To avoid name collisions, put keys with the same name in different namespaces. You can create a new or get an existing namespace with
@@ -156,7 +183,7 @@ function onChange(changes, values, data) {
156
183
  console.log("onChange", changes, values, data);
157
184
  }
158
185
 
159
- Varstor.add({
186
+ await Varstor.add({
160
187
  a: 10,
161
188
  b: 20,
162
189
  c: (a, b) => a + b,
@@ -185,12 +212,29 @@ Varstor.removeListener(onChange);
185
212
 
186
213
  const newNamespace = Varstor("new namespace");
187
214
 
188
- newNamespace.add({
189
- yyy: 1,
190
- zzz: 2,
215
+ await newNamespace.add({
216
+ x: 1,
217
+ y: 2,
218
+ z: 3,
191
219
  });
192
220
 
193
- newNamespace({ zzz: 3 });
221
+ newNamespace.actions({
222
+ logValues: ({ get }) => {
223
+ const { x, y, z } = get();
224
+ console.log(`x: ${x}, y: ${y}, z: ${z}`);
225
+ },
226
+ multiplyX: ({ get, set }, num) => set({ x: get().x * num }),
227
+ incrementY: ({ get, set }) => set({ y: get().y + 1 }),
228
+ })
229
+
230
+ const { logValues, multiplyX, incrementY } = newNamespace.get();
231
+
232
+ logValues(); // x: 1, y: 2, z: 3
233
+ multiplyX(10)
234
+ incrementY();
235
+ logValues(); // x: 10, y: 3, z: 3
236
+
237
+ await newNamespace({ z: 110 });
194
238
 
195
- console.log(Varstor("new namespace").get()); // {yyy: 1, zzz: 3}
239
+ console.log(Varstor("new namespace").get()); // {x: 10, y: 3, z: 110, logValues: ƒ, multiplyX: ƒ, …}
196
240
  ```
@@ -11,6 +11,39 @@
11
11
  return /******/ (() => { // webpackBootstrap
12
12
  /******/ var __webpack_modules__ = ({
13
13
 
14
+ /***/ "./src/actions.ts"
15
+ /*!************************!*\
16
+ !*** ./src/actions.ts ***!
17
+ \************************/
18
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
19
+
20
+ "use strict";
21
+ __webpack_require__.r(__webpack_exports__);
22
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
23
+ /* harmony export */ addStateActions: () => (/* binding */ addStateActions)
24
+ /* harmony export */ });
25
+ /* harmony import */ var ___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! . */ "./src/index.ts");
26
+
27
+ function addStateActions(namespace, actions) {
28
+ const stateAcessor = {
29
+ get: ___WEBPACK_IMPORTED_MODULE_0__.getState.bind(null, namespace),
30
+ set: ___WEBPACK_IMPORTED_MODULE_0__.setState.bind(null, namespace),
31
+ reset: ___WEBPACK_IMPORTED_MODULE_0__.resetState.bind(null, namespace),
32
+ };
33
+ for (let [actionName, actionFn] of Object.entries(actions)) {
34
+ ___WEBPACK_IMPORTED_MODULE_0__.STATE[namespace(actionName)] = {
35
+ key: actionName,
36
+ namespace,
37
+ value: actionFn.bind(null, stateAcessor),
38
+ isAction: true,
39
+ listeners: [],
40
+ };
41
+ }
42
+ }
43
+
44
+
45
+ /***/ },
46
+
14
47
  /***/ "./src/constants.ts"
15
48
  /*!**************************!*\
16
49
  !*** ./src/constants.ts ***!
@@ -118,13 +151,19 @@ __webpack_require__.r(__webpack_exports__);
118
151
  /* harmony export */ STATE: () => (/* binding */ STATE),
119
152
  /* harmony export */ createStore: () => (/* binding */ createStore),
120
153
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
121
- /* harmony export */ getValues: () => (/* binding */ getValues)
154
+ /* harmony export */ getState: () => (/* binding */ getState),
155
+ /* harmony export */ getValues: () => (/* binding */ getValues),
156
+ /* harmony export */ resetState: () => (/* binding */ resetState),
157
+ /* harmony export */ setState: () => (/* binding */ setState),
158
+ /* harmony export */ setupValue: () => (/* binding */ setupValue)
122
159
  /* harmony export */ });
123
160
  /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./storage */ "./src/storage.ts");
124
161
  /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ "./src/helpers.ts");
125
- /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants */ "./src/constants.ts");
126
- /* harmony import */ var _validation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./validation */ "./src/validation.ts");
127
- /* harmony import */ var _listeners__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./listeners */ "./src/listeners.ts");
162
+ /* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./actions */ "./src/actions.ts");
163
+ /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./constants */ "./src/constants.ts");
164
+ /* harmony import */ var _validation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./validation */ "./src/validation.ts");
165
+ /* harmony import */ var _listeners__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./listeners */ "./src/listeners.ts");
166
+
128
167
 
129
168
 
130
169
 
@@ -140,12 +179,12 @@ async function addState(namespace, initialState, isPersistent) {
140
179
  if (STORAGE.IS_AVAILABE(storageType)) {
141
180
  await STORAGE.UPDATE_STATE(values, storageType);
142
181
  }
143
- if (!_listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()]) {
144
- _listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()] = [];
182
+ if (!_listeners__WEBPACK_IMPORTED_MODULE_5__.LISTENERS[namespace()]) {
183
+ _listeners__WEBPACK_IMPORTED_MODULE_5__.LISTENERS[namespace()] = [];
145
184
  }
146
185
  for (const key in initialState) {
147
186
  const fullKey = namespace(key);
148
- _validation__WEBPACK_IMPORTED_MODULE_3__.isValid.Defining(fullKey);
187
+ _validation__WEBPACK_IMPORTED_MODULE_4__.isValid.Defining(fullKey);
149
188
  STATE[fullKey] = setupValue(key, namespace, values[fullKey], defaultValues[key], storageType);
150
189
  }
151
190
  return createStore(namespace());
@@ -210,7 +249,7 @@ async function onStateChange(changes) {
210
249
  }
211
250
  updateDependencies(key, changes, realChanges);
212
251
  }
213
- await (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.runStateChangeListeners)((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(realChanges, (k, v) => !v.isSame));
252
+ await (0,_listeners__WEBPACK_IMPORTED_MODULE_5__.runStateChangeListeners)((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(realChanges, (k, v) => !v.isSame));
214
253
  }
215
254
  function updateDependencies(key, changes, realChanges) {
216
255
  STATE[key].dependants?.forEach((name) => {
@@ -245,8 +284,8 @@ async function setState(namespace, changes) {
245
284
  const storageChanges = {};
246
285
  (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.forEach)(changes, (k, v) => {
247
286
  const fullKey = namespace(k);
248
- const { storageType, computeFn } = STATE[fullKey];
249
- if (computeFn) {
287
+ const { storageType, computeFn, isAction } = STATE[fullKey];
288
+ if (computeFn || isAction) {
250
289
  return;
251
290
  }
252
291
  if (!storageChanges[storageType]) {
@@ -280,7 +319,7 @@ function main(namespace) {
280
319
  return getState.apply(null, arguments);
281
320
  }
282
321
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isArray)(arguments[1])) {
283
- return _listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener.apply(null, arguments);
322
+ return _listeners__WEBPACK_IMPORTED_MODULE_5__.addStateListener.apply(null, arguments);
284
323
  }
285
324
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isObject)(arguments[1])) {
286
325
  return setState.apply(null, arguments);
@@ -290,7 +329,7 @@ function setStorageUtils(storageUtils) {
290
329
  Object.assign(STORAGE, storageUtils);
291
330
  }
292
331
  function addNamespace(namespace, str) {
293
- return `${namespace}${((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isString)(str) && _constants__WEBPACK_IMPORTED_MODULE_2__.NAMESPACE_DELIMITER) || ""}${str || ""}`;
332
+ return `${namespace}${((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isString)(str) && _constants__WEBPACK_IMPORTED_MODULE_3__.NAMESPACE_DELIMITER) || ""}${str || ""}`;
294
333
  }
295
334
  function createStore(_namespace) {
296
335
  const namespace = ((key) => addNamespace(_namespace, key));
@@ -300,8 +339,9 @@ function createStore(_namespace) {
300
339
  get: (newNamespace) => getState(namespace, newNamespace),
301
340
  set: async (changes) => await setState(namespace, changes),
302
341
  reset: (keys) => resetState(namespace, keys),
303
- onChange: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener)(namespace, keys, cb),
304
- removeListener: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.removeStateListener)(namespace, keys, cb),
342
+ onChange: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_5__.addStateListener)(namespace, keys, cb),
343
+ removeListener: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_5__.removeStateListener)(namespace, keys, cb),
344
+ actions: (actions) => (0,_actions__WEBPACK_IMPORTED_MODULE_2__.addStateActions)(namespace, actions),
305
345
  setStorageUtils,
306
346
  onStateChange,
307
347
  });
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see varstor-webextension.min.js.LICENSE.txt */
2
- !function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.Varstor=r():e.Varstor=r()}(this,()=>(()=>{var e={"./src/constants.ts"(e,r,s){"use strict";s.r(r),s.d(r,{NAMESPACE_DELIMITER:()=>n});const n="::"},"./src/helpers.ts"(e,r,s){"use strict";s.r(r),s.d(r,{filter:()=>u,forEach:()=>A,getParamNames:()=>l,isArray:()=>a,isFunction:()=>o,isObject:()=>g,isString:()=>i,map:()=>c,recreateStructure:()=>d});const n=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,t=/([^\s,]+)/g;function a(e){return"[object Array]"===m(e)}function i(e){return"[object String]"===m(e)}function o(e){return"[object Function]"===m(e)}function g(e){return"[object Object]"===m(e)}function m(e){return Object.prototype.toString.call(e)}function l(e){const r=e.toString().replace(n,"").split("=>")[0],s=r.slice(r.indexOf("(")+1,r.indexOf(")")).match(t);return null===s?[]:s}function c(e,r){const s=Object.entries(e).map(([e,s])=>r(e,s));return 2===s[0]?.length?Object.fromEntries(s):s}function A(e,r){Object.entries(e||{}).forEach(([e,s])=>r(e,s))}function u(e,r){return Object.fromEntries(Object.entries(e||{}).filter(([e,s])=>!0===r(e,s)))}function d(e){let r=e;if(a(e))return r=[],e.forEach(e=>r.push(d(e))),r;if(g(e)){r={};for(let s in e)r[s]=d(e[s]);return r}return r}},"./src/index.ts"(e,r,s){"use strict";s.r(r),s.d(r,{STATE:()=>g,createStore:()=>S,default:()=>w,getValues:()=>u});var n=s("./src/storage.ts"),t=s("./src/helpers.ts"),a=s("./src/constants.ts"),i=s("./src/validation.ts"),o=s("./src/listeners.ts");const g={},m={};async function l(e,r,s){const n=m.GET_TYPE(s),a=Object.assign({},r),l=(0,t.map)(r,(r,s)=>[e(r),s]);m.IS_AVAILABE(n)&&await m.UPDATE_STATE(l,n),o.LISTENERS[e()]||(o.LISTENERS[e()]=[]);for(const s in r){const r=e(s);i.isValid.Defining(r),g[r]=c(s,e,l[r],a[s],n)}return S(e())}function c(e,r,s,n,a){const i=r(e),o=(0,t.isFunction)(s),m=o?(0,t.getParamNames)(s):[];return m.forEach(e=>{const s=r(e);g[s]||(g[s]={dependants:[],dependencies:[],namespace:r,storageType:a}),g[s].dependants?.push(i)}),{key:e,fullKey:i,value:o?s.apply(null,d(m,r)):s,computeFn:o&&s,dependencies:m,dependants:[],listeners:[],defaultValue:n,storageType:a,namespace:r}}function A(e){return(0,t.filter)(g,(r,{key:s})=>r===e(s))}function u(e){return(0,t.map)(A(e),(e,{key:r,value:s})=>[r,s])}function d(e,r){const s=u(r);return e.map(e=>s[e])}async function x(e){const r={};for(const s in e){const n=g[s].value,t=e[s].newValue;n!==t?(r[s]={newValue:t,prevValue:n},g[s].value=t):r[s]={isSame:!0},f(s,e,r)}await(0,o.runStateChangeListeners)((0,t.filter)(r,(e,r)=>!r.isSame))}function f(e,r,s){g[e].dependants?.forEach(e=>{const{dependencies:n,namespace:t}=g[e];if(!function(e,r,s,n){return e.every(e=>{const t=r(e);return s.includes(t)&&n.includes(t)||!s.includes(t)})}(n,t,Object.keys(r),Object.keys(s))||s[e])return;const a=g[e].value,i=g[e].computeFn?.apply(null,d(n,t));a!==i&&(s[e]={newValue:i,prevValue:a},g[e].value=i,f(e,r,s))})}function p(e,r){return(0,t.isString)(r)?S(r):(0,t.recreateStructure)(u(e))}async function b(e,r){const s={};(0,t.forEach)(r,(r,n)=>{const t=e(r),{storageType:a,computeFn:i}=g[t];i||(s[a]||(s[a]={}),s[a][t]=n)});for(let[e,r]of Object.entries(s))await h(e,r);return S(e())}async function h(e,r){if(m.IS_AVAILABE(e)){if(await m.SET_VALUES(e,r))return}x((0,t.map)(r,(e,r)=>[e,{newValue:r}]))}function E(e){return!arguments[1]||(0,t.isString)(arguments[1])?p.apply(null,arguments):(0,t.isArray)(arguments[1])?o.addStateListener.apply(null,arguments):(0,t.isObject)(arguments[1])?b.apply(null,arguments):void 0}function y(e){Object.assign(m,e)}function S(e){const r=r=>function(e,r){return`${e}${(0,t.isString)(r)&&a.NAMESPACE_DELIMITER||""}${r||""}`}(e,r);return Object.assign(E.bind(null,r),{add:e=>l(r,e,!1),addPersistent:e=>l(r,e,!0),get:e=>p(r,e),set:async e=>await b(r,e),reset:e=>async function(e,r){const s=A(e);return await b(e,(0,t.map)(r?(0,t.filter)(s,(e,{key:s})=>r.includes(s)):s,(e,{key:r,defaultValue:s})=>[r,s])),S(e())}(r,e),onChange:(e,s)=>(0,o.addStateListener)(r,e,s),removeListener:(e,s)=>(0,o.removeStateListener)(r,e,s),setStorageUtils:y,onStateChange:x})}y(n.default);const w=S("")},"./src/listeners.ts"(e,r,s){"use strict";s.r(r),s.d(r,{LISTENERS:()=>i,addStateListener:()=>g,removeStateListener:()=>m,runStateChangeListeners:()=>o});var n=s("./src/index.ts"),t=s("./src/constants.ts"),a=s("./src/helpers.ts");const i={};async function o(e){if(Object.keys(e).length){const{namespace:r}=n.STATE[Object.keys(e)[0]],s=(0,n.getValues)(r);for(let[r,t]of Object.entries(e)){const{listeners:e,key:a}=n.STATE[r];for(const r of e)await r([a],s,t)}const o=(0,a.map)(e,e=>e.slice(t.NAMESPACE_DELIMITER.length));for(const n of i[r()])await n(o,s,(0,a.map)(e,(e,r)=>[e.slice(t.NAMESPACE_DELIMITER.length),r]))}}function g(e,r,s){return(0,a.isFunction)(r)?(i[e()].push(r),(0,n.createStore)(e())):(r.forEach(r=>n.STATE[e(r)].listeners?.push(s)),(0,n.createStore)(e()))}function m(e,r,s){if((0,a.isFunction)(r)){const s=i[e()].findIndex(e=>e===r);return i[e()].splice(s,1),(0,n.createStore)(e())}return r.forEach(r=>{const t=n.STATE[e(r)].listeners,a=t?.findIndex(e=>e===s);t?.splice(a,1)}),(0,n.createStore)(e())}},"./src/storage.ts"(e,r,s){"use strict";s.r(r),s.d(r,{default:()=>n});const n={GET_TYPE:function(e){return e?"localStorage":""},IS_AVAILABE:function(e){return!!e},UPDATE_STATE:async function(e){const r={};for(const s in e){const e=localStorage.getItem(s);null!==e&&(r[s]=e)}return Object.assign(e,r)},SET_VALUES:async function(e,r){for(let[e,s]of Object.entries(r))localStorage.setItem(e,s);return!1}}},"./src/validation.ts"(e,r,s){"use strict";s.r(r),s.d(r,{isValid:()=>i});var n=s("./src/index.ts"),t=s("./src/constants.ts");function a(e){const r=e.split(t.NAMESPACE_DELIMITER);return[r.slice(-1)[0],r.join(t.NAMESPACE_DELIMITER)]}const i={Setting:e=>{if(!n.STATE[e]){const[r,s]=a(e);throw new Error(`Setting "${r}" key in "${s}" namespace. DOES NOT EXIST`)}return!0},Defining:e=>{if(n.STATE[e]){const[r,s]=a(e);throw new Error(`Redefining "${r}" key in "${s}" namespace. ALREADY DEFINED`)}return!0}}},"./src/webextension-storage.ts"(e,r,s){"use strict";s.r(r),s.d(r,{default:()=>t,isBackgroundScript:()=>i,isSessionStorageSupport:()=>a});const n=s("./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"),t={GET_TYPE:function(e){return i()&&e?"local":"session"},IS_AVAILABE:function(e){return"local"===e||"session"===e&&a()},UPDATE_STATE:async function(e,r){return Object.assign(e,await n.storage[r].get())},SET_VALUES:async function(e,r){return await n.storage[e].set(r),!0}};function a(){return!!n.storage.session}function i(){return"chrome-extension:"===window.location.protocol||"moz-extension:"===window.location.protocol}},"./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"(e,r){var s,n,t;"undefined"==typeof globalThis?"undefined"==typeof self||self:globalThis,n=[e],void 0===(t="function"==typeof(s=function(e){"use strict";if(!(globalThis.chrome&&globalThis.chrome.runtime&&globalThis.chrome.runtime.id))throw new Error("This script should only be loaded in a browser extension.");globalThis.browser&&globalThis.browser.runtime&&globalThis.browser.runtime.id?e.exports=globalThis.browser:e.exports=(e=>{const r={alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getSubTree:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{disable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},enable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},openPopup:{minArgs:0,maxArgs:0},setBadgeBackgroundColor:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setBadgeText:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},browsingData:{remove:{minArgs:2,maxArgs:2},removeCache:{minArgs:1,maxArgs:1},removeCookies:{minArgs:1,maxArgs:1},removeDownloads:{minArgs:1,maxArgs:1},removeFormData:{minArgs:1,maxArgs:1},removeHistory:{minArgs:1,maxArgs:1},removeLocalStorage:{minArgs:1,maxArgs:1},removePasswords:{minArgs:1,maxArgs:1},removePluginData:{minArgs:1,maxArgs:1},settings:{minArgs:0,maxArgs:0}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},devtools:{inspectedWindow:{eval:{minArgs:1,maxArgs:2,singleCallbackArg:!1}},panels:{create:{minArgs:3,maxArgs:3,singleCallbackArg:!0},elements:{createSidebarPane:{minArgs:1,maxArgs:1}}}},downloads:{cancel:{minArgs:1,maxArgs:1},download:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},identity:{launchWebAuthFlow:{minArgs:1,maxArgs:1}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},setEnabled:{minArgs:2,maxArgs:2},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},permissions:{contains:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},request:{minArgs:1,maxArgs:1}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},sessions:{getDevices:{minArgs:0,maxArgs:1},getRecentlyClosed:{minArgs:0,maxArgs:1},restore:{minArgs:0,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{captureVisibleTab:{minArgs:0,maxArgs:2},create:{minArgs:1,maxArgs:1},detectLanguage:{minArgs:0,maxArgs:1},discard:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},goBack:{minArgs:0,maxArgs:1},goForward:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},query:{minArgs:1,maxArgs:1},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},topSites:{get:{minArgs:0,maxArgs:0}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}};if(0===Object.keys(r).length)throw new Error("api-metadata.json has not been included in browser-polyfill");class s extends WeakMap{constructor(e,r=void 0){super(r),this.createItem=e}get(e){return this.has(e)||this.set(e,this.createItem(e)),super.get(e)}}const n=e=>e&&"object"==typeof e&&"function"==typeof e.then,t=(r,s)=>(...n)=>{e.runtime.lastError?r.reject(new Error(e.runtime.lastError.message)):s.singleCallbackArg||1>=n.length&&!1!==s.singleCallbackArg?r.resolve(n[0]):r.resolve(n)},a=e=>1==e?"argument":"arguments",i=(e,r)=>function(s,...n){if(n.length<r.minArgs)throw new Error(`Expected at least ${r.minArgs} ${a(r.minArgs)} for ${e}(), got ${n.length}`);if(n.length>r.maxArgs)throw new Error(`Expected at most ${r.maxArgs} ${a(r.maxArgs)} for ${e}(), got ${n.length}`);return new Promise((a,i)=>{if(r.fallbackToNoCallback)try{s[e](...n,t({resolve:a,reject:i},r))}catch(t){console.warn(`${e} API method doesn't seem to support the callback parameter, falling back to call it without a callback: `,t),s[e](...n),r.fallbackToNoCallback=!1,r.noCallback=!0,a()}else r.noCallback?(s[e](...n),a()):s[e](...n,t({resolve:a,reject:i},r))})},o=(e,r,s)=>new Proxy(r,{apply:(r,n,t)=>s.call(n,e,...t)});let g=Function.call.bind(Object.prototype.hasOwnProperty);const m=(e,r={},s={})=>{let n=Object.create(null),t=Object.create(e);return new Proxy(t,{has:(r,s)=>s in e||s in n,get(t,a){if(a in n)return n[a];if(!(a in e))return;let l=e[a];if("function"==typeof l)if("function"==typeof r[a])l=o(e,e[a],r[a]);else if(g(s,a)){let r=i(a,s[a]);l=o(e,e[a],r)}else l=l.bind(e);else if("object"==typeof l&&null!==l&&(g(r,a)||g(s,a)))l=m(l,r[a],s[a]);else{if(!g(s,"*"))return Object.defineProperty(n,a,{configurable:!0,enumerable:!0,get:()=>e[a],set(r){e[a]=r}}),l;l=m(l,r[a],s["*"])}return n[a]=l,l},set:(r,s,t)=>(s in n?n[s]=t:e[s]=t,!0),defineProperty:(e,r,s)=>Reflect.defineProperty(n,r,s),deleteProperty:(e,r)=>Reflect.deleteProperty(n,r)})},l=e=>({addListener(r,s,...n){r.addListener(e.get(s),...n)},hasListener:(r,s)=>r.hasListener(e.get(s)),removeListener(r,s){r.removeListener(e.get(s))}}),c=new s(e=>"function"==typeof e?function(r){const s=m(r,{},{getContent:{minArgs:0,maxArgs:0}});e(s)}:e),A=new s(e=>"function"==typeof e?function(r,s,t){let a,i,o=!1,g=new Promise(e=>{a=function(r){o=!0,e(r)}});try{i=e(r,s,a)}catch(e){i=Promise.reject(e)}const m=!0!==i&&n(i);if(!0!==i&&!m&&!o)return!1;const l=e=>{e.then(e=>{t(e)},e=>{let r;r=e&&(e instanceof Error||"string"==typeof e.message)?e.message:"An unexpected error occurred",t({__mozWebExtensionPolyfillReject__:!0,message:r})}).catch(e=>{console.error("Failed to send onMessage rejected reply",e)})};return l(m?i:g),!0}:e),u=({reject:r,resolve:s},n)=>{e.runtime.lastError?"The message port closed before a response was received."===e.runtime.lastError.message?s():r(new Error(e.runtime.lastError.message)):n&&n.__mozWebExtensionPolyfillReject__?r(new Error(n.message)):s(n)},d=(e,r,s,...n)=>{if(n.length<r.minArgs)throw new Error(`Expected at least ${r.minArgs} ${a(r.minArgs)} for ${e}(), got ${n.length}`);if(n.length>r.maxArgs)throw new Error(`Expected at most ${r.maxArgs} ${a(r.maxArgs)} for ${e}(), got ${n.length}`);return new Promise((e,r)=>{const t=u.bind(null,{resolve:e,reject:r});n.push(t),s.sendMessage(...n)})},x={devtools:{network:{onRequestFinished:l(c)}},runtime:{onMessage:l(A),onMessageExternal:l(A),sendMessage:d.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:d.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},f={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return r.privacy={network:{"*":f},services:{"*":f},websites:{"*":f}},m(e,x,r)})(chrome)})?s.apply(r,n):s)||(e.exports=t)}};const r={};function s(n){const t=r[n];if(void 0!==t)return t.exports;const a=r[n]={exports:{}};if(!(n in e)){delete r[n];const e=new Error("Cannot find module '"+n+"'");throw e.code="MODULE_NOT_FOUND",e}return e[n].call(a.exports,a,a.exports,s),a.exports}s.d=(e,r)=>{if(Array.isArray(r))for(var n=0;n<r.length;){var t=r[n++],a=r[n++];s.o(e,t)?0===a&&n++:0===a?Object.defineProperty(e,t,{enumerable:!0,value:r[n++]}):Object.defineProperty(e,t,{enumerable:!0,get:a})}else for(var t in r)s.o(r,t)&&!s.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},s.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),s.r=e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};let n={};return(()=>{"use strict";s.r(n),s.d(n,{default:()=>o});var e=s("./src/index.ts"),r=s("./src/webextension-storage.ts");const t=s("./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"),{onStateChange:a,setStorageUtils:i}=e.default;(0,r.isBackgroundScript)()&&(t.storage.local.onChanged.addListener(a),(0,r.isSessionStorageSupport)()&&t.storage.session.onChanged.addListener(a)),i(r.default);const o=e.default})(),n=n.default,n})());
2
+ !function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.Varstor=r():e.Varstor=r()}(this,()=>(()=>{var e={"./src/actions.ts"(e,r,s){"use strict";s.r(r),s.d(r,{addStateActions:()=>n});var t=s("./src/index.ts");function n(e,r){const s={get:t.getState.bind(null,e),set:t.setState.bind(null,e),reset:t.resetState.bind(null,e)};for(let[n,a]of Object.entries(r))t.STATE[e(n)]={key:n,namespace:e,value:a.bind(null,s),isAction:!0,listeners:[]}}},"./src/constants.ts"(e,r,s){"use strict";s.r(r),s.d(r,{NAMESPACE_DELIMITER:()=>t});const t="::"},"./src/helpers.ts"(e,r,s){"use strict";s.r(r),s.d(r,{filter:()=>u,forEach:()=>A,getParamNames:()=>l,isArray:()=>a,isFunction:()=>o,isObject:()=>g,isString:()=>i,map:()=>c,recreateStructure:()=>d});const t=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,n=/([^\s,]+)/g;function a(e){return"[object Array]"===m(e)}function i(e){return"[object String]"===m(e)}function o(e){return"[object Function]"===m(e)}function g(e){return"[object Object]"===m(e)}function m(e){return Object.prototype.toString.call(e)}function l(e){const r=e.toString().replace(t,"").split("=>")[0],s=r.slice(r.indexOf("(")+1,r.indexOf(")")).match(n);return null===s?[]:s}function c(e,r){const s=Object.entries(e).map(([e,s])=>r(e,s));return 2===s[0]?.length?Object.fromEntries(s):s}function A(e,r){Object.entries(e||{}).forEach(([e,s])=>r(e,s))}function u(e,r){return Object.fromEntries(Object.entries(e||{}).filter(([e,s])=>!0===r(e,s)))}function d(e){let r=e;if(a(e))return r=[],e.forEach(e=>r.push(d(e))),r;if(g(e)){r={};for(let s in e)r[s]=d(e[s]);return r}return r}},"./src/index.ts"(e,r,s){"use strict";s.r(r),s.d(r,{STATE:()=>m,createStore:()=>w,default:()=>v,getState:()=>b,getValues:()=>d,resetState:()=>E,setState:()=>h,setupValue:()=>A});var t=s("./src/storage.ts"),n=s("./src/helpers.ts"),a=s("./src/actions.ts"),i=s("./src/constants.ts"),o=s("./src/validation.ts"),g=s("./src/listeners.ts");const m={},l={};async function c(e,r,s){const t=l.GET_TYPE(s),a=Object.assign({},r),i=(0,n.map)(r,(r,s)=>[e(r),s]);l.IS_AVAILABE(t)&&await l.UPDATE_STATE(i,t),g.LISTENERS[e()]||(g.LISTENERS[e()]=[]);for(const s in r){const r=e(s);o.isValid.Defining(r),m[r]=A(s,e,i[r],a[s],t)}return w(e())}function A(e,r,s,t,a){const i=r(e),o=(0,n.isFunction)(s),g=o?(0,n.getParamNames)(s):[];return g.forEach(e=>{const s=r(e);m[s]||(m[s]={dependants:[],dependencies:[],namespace:r,storageType:a}),m[s].dependants?.push(i)}),{key:e,fullKey:i,value:o?s.apply(null,x(g,r)):s,computeFn:o&&s,dependencies:g,dependants:[],listeners:[],defaultValue:t,storageType:a,namespace:r}}function u(e){return(0,n.filter)(m,(r,{key:s})=>r===e(s))}function d(e){return(0,n.map)(u(e),(e,{key:r,value:s})=>[r,s])}function x(e,r){const s=d(r);return e.map(e=>s[e])}async function f(e){const r={};for(const s in e){const t=m[s].value,n=e[s].newValue;t!==n?(r[s]={newValue:n,prevValue:t},m[s].value=n):r[s]={isSame:!0},p(s,e,r)}await(0,g.runStateChangeListeners)((0,n.filter)(r,(e,r)=>!r.isSame))}function p(e,r,s){m[e].dependants?.forEach(e=>{const{dependencies:t,namespace:n}=m[e];if(!function(e,r,s,t){return e.every(e=>{const n=r(e);return s.includes(n)&&t.includes(n)||!s.includes(n)})}(t,n,Object.keys(r),Object.keys(s))||s[e])return;const a=m[e].value,i=m[e].computeFn?.apply(null,x(t,n));a!==i&&(s[e]={newValue:i,prevValue:a},m[e].value=i,p(e,r,s))})}function b(e,r){return(0,n.isString)(r)?w(r):(0,n.recreateStructure)(d(e))}async function h(e,r){const s={};(0,n.forEach)(r,(r,t)=>{const n=e(r),{storageType:a,computeFn:i,isAction:o}=m[n];i||o||(s[a]||(s[a]={}),s[a][n]=t)});for(let[e,r]of Object.entries(s))await S(e,r);return w(e())}async function S(e,r){if(l.IS_AVAILABE(e)){if(await l.SET_VALUES(e,r))return}f((0,n.map)(r,(e,r)=>[e,{newValue:r}]))}async function E(e,r){const s=u(e);return await h(e,(0,n.map)(r?(0,n.filter)(s,(e,{key:s})=>r.includes(s)):s,(e,{key:r,defaultValue:s})=>[r,s])),w(e())}function y(e){return!arguments[1]||(0,n.isString)(arguments[1])?b.apply(null,arguments):(0,n.isArray)(arguments[1])?g.addStateListener.apply(null,arguments):(0,n.isObject)(arguments[1])?h.apply(null,arguments):void 0}function T(e){Object.assign(l,e)}function w(e){const r=r=>function(e,r){return`${e}${(0,n.isString)(r)&&i.NAMESPACE_DELIMITER||""}${r||""}`}(e,r);return Object.assign(y.bind(null,r),{add:e=>c(r,e,!1),addPersistent:e=>c(r,e,!0),get:e=>b(r,e),set:async e=>await h(r,e),reset:e=>E(r,e),onChange:(e,s)=>(0,g.addStateListener)(r,e,s),removeListener:(e,s)=>(0,g.removeStateListener)(r,e,s),actions:e=>(0,a.addStateActions)(r,e),setStorageUtils:T,onStateChange:f})}T(t.default);const v=w("")},"./src/listeners.ts"(e,r,s){"use strict";s.r(r),s.d(r,{LISTENERS:()=>i,addStateListener:()=>g,removeStateListener:()=>m,runStateChangeListeners:()=>o});var t=s("./src/index.ts"),n=s("./src/constants.ts"),a=s("./src/helpers.ts");const i={};async function o(e){if(Object.keys(e).length){const{namespace:r}=t.STATE[Object.keys(e)[0]],s=(0,t.getValues)(r);for(let[r,n]of Object.entries(e)){const{listeners:e,key:a}=t.STATE[r];for(const r of e)await r([a],s,n)}const o=(0,a.map)(e,e=>e.slice(n.NAMESPACE_DELIMITER.length));for(const t of i[r()])await t(o,s,(0,a.map)(e,(e,r)=>[e.slice(n.NAMESPACE_DELIMITER.length),r]))}}function g(e,r,s){return(0,a.isFunction)(r)?(i[e()].push(r),(0,t.createStore)(e())):(r.forEach(r=>t.STATE[e(r)].listeners?.push(s)),(0,t.createStore)(e()))}function m(e,r,s){if((0,a.isFunction)(r)){const s=i[e()].findIndex(e=>e===r);return i[e()].splice(s,1),(0,t.createStore)(e())}return r.forEach(r=>{const n=t.STATE[e(r)].listeners,a=n?.findIndex(e=>e===s);n?.splice(a,1)}),(0,t.createStore)(e())}},"./src/storage.ts"(e,r,s){"use strict";s.r(r),s.d(r,{default:()=>t});const t={GET_TYPE:function(e){return e?"localStorage":""},IS_AVAILABE:function(e){return!!e},UPDATE_STATE:async function(e){const r={};for(const s in e){const e=localStorage.getItem(s);null!==e&&(r[s]=e)}return Object.assign(e,r)},SET_VALUES:async function(e,r){for(let[e,s]of Object.entries(r))localStorage.setItem(e,s);return!1}}},"./src/validation.ts"(e,r,s){"use strict";s.r(r),s.d(r,{isValid:()=>i});var t=s("./src/index.ts"),n=s("./src/constants.ts");function a(e){const r=e.split(n.NAMESPACE_DELIMITER);return[r.slice(-1)[0],r.join(n.NAMESPACE_DELIMITER)]}const i={Setting:e=>{if(!t.STATE[e]){const[r,s]=a(e);throw new Error(`Setting "${r}" key in "${s}" namespace. DOES NOT EXIST`)}return!0},Defining:e=>{if(t.STATE[e]){const[r,s]=a(e);throw new Error(`Redefining "${r}" key in "${s}" namespace. ALREADY DEFINED`)}return!0}}},"./src/webextension-storage.ts"(e,r,s){"use strict";s.r(r),s.d(r,{default:()=>n,isBackgroundScript:()=>i,isSessionStorageSupport:()=>a});const t=s("./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"),n={GET_TYPE:function(e){return i()&&e?"local":"session"},IS_AVAILABE:function(e){return"local"===e||"session"===e&&a()},UPDATE_STATE:async function(e,r){return Object.assign(e,await t.storage[r].get())},SET_VALUES:async function(e,r){return await t.storage[e].set(r),!0}};function a(){return!!t.storage.session}function i(){return"chrome-extension:"===window.location.protocol||"moz-extension:"===window.location.protocol}},"./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"(e,r){var s,t,n;"undefined"==typeof globalThis?"undefined"==typeof self||self:globalThis,t=[e],void 0===(n="function"==typeof(s=function(e){"use strict";if(!(globalThis.chrome&&globalThis.chrome.runtime&&globalThis.chrome.runtime.id))throw new Error("This script should only be loaded in a browser extension.");globalThis.browser&&globalThis.browser.runtime&&globalThis.browser.runtime.id?e.exports=globalThis.browser:e.exports=(e=>{const r={alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getSubTree:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{disable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},enable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},openPopup:{minArgs:0,maxArgs:0},setBadgeBackgroundColor:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setBadgeText:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},browsingData:{remove:{minArgs:2,maxArgs:2},removeCache:{minArgs:1,maxArgs:1},removeCookies:{minArgs:1,maxArgs:1},removeDownloads:{minArgs:1,maxArgs:1},removeFormData:{minArgs:1,maxArgs:1},removeHistory:{minArgs:1,maxArgs:1},removeLocalStorage:{minArgs:1,maxArgs:1},removePasswords:{minArgs:1,maxArgs:1},removePluginData:{minArgs:1,maxArgs:1},settings:{minArgs:0,maxArgs:0}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},devtools:{inspectedWindow:{eval:{minArgs:1,maxArgs:2,singleCallbackArg:!1}},panels:{create:{minArgs:3,maxArgs:3,singleCallbackArg:!0},elements:{createSidebarPane:{minArgs:1,maxArgs:1}}}},downloads:{cancel:{minArgs:1,maxArgs:1},download:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},identity:{launchWebAuthFlow:{minArgs:1,maxArgs:1}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},setEnabled:{minArgs:2,maxArgs:2},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},permissions:{contains:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},request:{minArgs:1,maxArgs:1}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},sessions:{getDevices:{minArgs:0,maxArgs:1},getRecentlyClosed:{minArgs:0,maxArgs:1},restore:{minArgs:0,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{captureVisibleTab:{minArgs:0,maxArgs:2},create:{minArgs:1,maxArgs:1},detectLanguage:{minArgs:0,maxArgs:1},discard:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},goBack:{minArgs:0,maxArgs:1},goForward:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},query:{minArgs:1,maxArgs:1},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},topSites:{get:{minArgs:0,maxArgs:0}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}};if(0===Object.keys(r).length)throw new Error("api-metadata.json has not been included in browser-polyfill");class s extends WeakMap{constructor(e,r=void 0){super(r),this.createItem=e}get(e){return this.has(e)||this.set(e,this.createItem(e)),super.get(e)}}const t=e=>e&&"object"==typeof e&&"function"==typeof e.then,n=(r,s)=>(...t)=>{e.runtime.lastError?r.reject(new Error(e.runtime.lastError.message)):s.singleCallbackArg||1>=t.length&&!1!==s.singleCallbackArg?r.resolve(t[0]):r.resolve(t)},a=e=>1==e?"argument":"arguments",i=(e,r)=>function(s,...t){if(t.length<r.minArgs)throw new Error(`Expected at least ${r.minArgs} ${a(r.minArgs)} for ${e}(), got ${t.length}`);if(t.length>r.maxArgs)throw new Error(`Expected at most ${r.maxArgs} ${a(r.maxArgs)} for ${e}(), got ${t.length}`);return new Promise((a,i)=>{if(r.fallbackToNoCallback)try{s[e](...t,n({resolve:a,reject:i},r))}catch(n){console.warn(`${e} API method doesn't seem to support the callback parameter, falling back to call it without a callback: `,n),s[e](...t),r.fallbackToNoCallback=!1,r.noCallback=!0,a()}else r.noCallback?(s[e](...t),a()):s[e](...t,n({resolve:a,reject:i},r))})},o=(e,r,s)=>new Proxy(r,{apply:(r,t,n)=>s.call(t,e,...n)});let g=Function.call.bind(Object.prototype.hasOwnProperty);const m=(e,r={},s={})=>{let t=Object.create(null),n=Object.create(e);return new Proxy(n,{has:(r,s)=>s in e||s in t,get(n,a){if(a in t)return t[a];if(!(a in e))return;let l=e[a];if("function"==typeof l)if("function"==typeof r[a])l=o(e,e[a],r[a]);else if(g(s,a)){let r=i(a,s[a]);l=o(e,e[a],r)}else l=l.bind(e);else if("object"==typeof l&&null!==l&&(g(r,a)||g(s,a)))l=m(l,r[a],s[a]);else{if(!g(s,"*"))return Object.defineProperty(t,a,{configurable:!0,enumerable:!0,get:()=>e[a],set(r){e[a]=r}}),l;l=m(l,r[a],s["*"])}return t[a]=l,l},set:(r,s,n)=>(s in t?t[s]=n:e[s]=n,!0),defineProperty:(e,r,s)=>Reflect.defineProperty(t,r,s),deleteProperty:(e,r)=>Reflect.deleteProperty(t,r)})},l=e=>({addListener(r,s,...t){r.addListener(e.get(s),...t)},hasListener:(r,s)=>r.hasListener(e.get(s)),removeListener(r,s){r.removeListener(e.get(s))}}),c=new s(e=>"function"==typeof e?function(r){const s=m(r,{},{getContent:{minArgs:0,maxArgs:0}});e(s)}:e),A=new s(e=>"function"==typeof e?function(r,s,n){let a,i,o=!1,g=new Promise(e=>{a=function(r){o=!0,e(r)}});try{i=e(r,s,a)}catch(e){i=Promise.reject(e)}const m=!0!==i&&t(i);if(!0!==i&&!m&&!o)return!1;const l=e=>{e.then(e=>{n(e)},e=>{let r;r=e&&(e instanceof Error||"string"==typeof e.message)?e.message:"An unexpected error occurred",n({__mozWebExtensionPolyfillReject__:!0,message:r})}).catch(e=>{console.error("Failed to send onMessage rejected reply",e)})};return l(m?i:g),!0}:e),u=({reject:r,resolve:s},t)=>{e.runtime.lastError?"The message port closed before a response was received."===e.runtime.lastError.message?s():r(new Error(e.runtime.lastError.message)):t&&t.__mozWebExtensionPolyfillReject__?r(new Error(t.message)):s(t)},d=(e,r,s,...t)=>{if(t.length<r.minArgs)throw new Error(`Expected at least ${r.minArgs} ${a(r.minArgs)} for ${e}(), got ${t.length}`);if(t.length>r.maxArgs)throw new Error(`Expected at most ${r.maxArgs} ${a(r.maxArgs)} for ${e}(), got ${t.length}`);return new Promise((e,r)=>{const n=u.bind(null,{resolve:e,reject:r});t.push(n),s.sendMessage(...t)})},x={devtools:{network:{onRequestFinished:l(c)}},runtime:{onMessage:l(A),onMessageExternal:l(A),sendMessage:d.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:d.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},f={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return r.privacy={network:{"*":f},services:{"*":f},websites:{"*":f}},m(e,x,r)})(chrome)})?s.apply(r,t):s)||(e.exports=n)}};const r={};function s(t){const n=r[t];if(void 0!==n)return n.exports;const a=r[t]={exports:{}};if(!(t in e)){delete r[t];const e=new Error("Cannot find module '"+t+"'");throw e.code="MODULE_NOT_FOUND",e}return e[t].call(a.exports,a,a.exports,s),a.exports}s.d=(e,r)=>{if(Array.isArray(r))for(var t=0;t<r.length;){var n=r[t++],a=r[t++];s.o(e,n)?0===a&&t++:0===a?Object.defineProperty(e,n,{enumerable:!0,value:r[t++]}):Object.defineProperty(e,n,{enumerable:!0,get:a})}else for(var n in r)s.o(r,n)&&!s.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:r[n]})},s.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),s.r=e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};let t={};return(()=>{"use strict";s.r(t),s.d(t,{default:()=>o});var e=s("./src/index.ts"),r=s("./src/webextension-storage.ts");const n=s("./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"),{onStateChange:a,setStorageUtils:i}=e.default;(0,r.isBackgroundScript)()&&(n.storage.local.onChanged.addListener(a),(0,r.isSessionStorageSupport)()&&n.storage.session.onChanged.addListener(a)),i(r.default);const o=e.default})(),t=t.default,t})());
package/dist/varstor.js CHANGED
@@ -12,6 +12,38 @@ return /******/ (() => { // webpackBootstrap
12
12
  /******/ "use strict";
13
13
  /******/ var __webpack_modules__ = ({
14
14
 
15
+ /***/ "./src/actions.ts"
16
+ /*!************************!*\
17
+ !*** ./src/actions.ts ***!
18
+ \************************/
19
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
20
+
21
+ __webpack_require__.r(__webpack_exports__);
22
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
23
+ /* harmony export */ addStateActions: () => (/* binding */ addStateActions)
24
+ /* harmony export */ });
25
+ /* harmony import */ var ___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! . */ "./src/index.ts");
26
+
27
+ function addStateActions(namespace, actions) {
28
+ const stateAcessor = {
29
+ get: ___WEBPACK_IMPORTED_MODULE_0__.getState.bind(null, namespace),
30
+ set: ___WEBPACK_IMPORTED_MODULE_0__.setState.bind(null, namespace),
31
+ reset: ___WEBPACK_IMPORTED_MODULE_0__.resetState.bind(null, namespace),
32
+ };
33
+ for (let [actionName, actionFn] of Object.entries(actions)) {
34
+ ___WEBPACK_IMPORTED_MODULE_0__.STATE[namespace(actionName)] = {
35
+ key: actionName,
36
+ namespace,
37
+ value: actionFn.bind(null, stateAcessor),
38
+ isAction: true,
39
+ listeners: [],
40
+ };
41
+ }
42
+ }
43
+
44
+
45
+ /***/ },
46
+
15
47
  /***/ "./src/constants.ts"
16
48
  /*!**************************!*\
17
49
  !*** ./src/constants.ts ***!
@@ -116,13 +148,19 @@ __webpack_require__.r(__webpack_exports__);
116
148
  /* harmony export */ STATE: () => (/* binding */ STATE),
117
149
  /* harmony export */ createStore: () => (/* binding */ createStore),
118
150
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
119
- /* harmony export */ getValues: () => (/* binding */ getValues)
151
+ /* harmony export */ getState: () => (/* binding */ getState),
152
+ /* harmony export */ getValues: () => (/* binding */ getValues),
153
+ /* harmony export */ resetState: () => (/* binding */ resetState),
154
+ /* harmony export */ setState: () => (/* binding */ setState),
155
+ /* harmony export */ setupValue: () => (/* binding */ setupValue)
120
156
  /* harmony export */ });
121
157
  /* harmony import */ var _storage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./storage */ "./src/storage.ts");
122
158
  /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ "./src/helpers.ts");
123
- /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants */ "./src/constants.ts");
124
- /* harmony import */ var _validation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./validation */ "./src/validation.ts");
125
- /* harmony import */ var _listeners__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./listeners */ "./src/listeners.ts");
159
+ /* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./actions */ "./src/actions.ts");
160
+ /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./constants */ "./src/constants.ts");
161
+ /* harmony import */ var _validation__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./validation */ "./src/validation.ts");
162
+ /* harmony import */ var _listeners__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./listeners */ "./src/listeners.ts");
163
+
126
164
 
127
165
 
128
166
 
@@ -138,12 +176,12 @@ async function addState(namespace, initialState, isPersistent) {
138
176
  if (STORAGE.IS_AVAILABE(storageType)) {
139
177
  await STORAGE.UPDATE_STATE(values, storageType);
140
178
  }
141
- if (!_listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()]) {
142
- _listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()] = [];
179
+ if (!_listeners__WEBPACK_IMPORTED_MODULE_5__.LISTENERS[namespace()]) {
180
+ _listeners__WEBPACK_IMPORTED_MODULE_5__.LISTENERS[namespace()] = [];
143
181
  }
144
182
  for (const key in initialState) {
145
183
  const fullKey = namespace(key);
146
- _validation__WEBPACK_IMPORTED_MODULE_3__.isValid.Defining(fullKey);
184
+ _validation__WEBPACK_IMPORTED_MODULE_4__.isValid.Defining(fullKey);
147
185
  STATE[fullKey] = setupValue(key, namespace, values[fullKey], defaultValues[key], storageType);
148
186
  }
149
187
  return createStore(namespace());
@@ -208,7 +246,7 @@ async function onStateChange(changes) {
208
246
  }
209
247
  updateDependencies(key, changes, realChanges);
210
248
  }
211
- await (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.runStateChangeListeners)((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(realChanges, (k, v) => !v.isSame));
249
+ await (0,_listeners__WEBPACK_IMPORTED_MODULE_5__.runStateChangeListeners)((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(realChanges, (k, v) => !v.isSame));
212
250
  }
213
251
  function updateDependencies(key, changes, realChanges) {
214
252
  STATE[key].dependants?.forEach((name) => {
@@ -243,8 +281,8 @@ async function setState(namespace, changes) {
243
281
  const storageChanges = {};
244
282
  (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.forEach)(changes, (k, v) => {
245
283
  const fullKey = namespace(k);
246
- const { storageType, computeFn } = STATE[fullKey];
247
- if (computeFn) {
284
+ const { storageType, computeFn, isAction } = STATE[fullKey];
285
+ if (computeFn || isAction) {
248
286
  return;
249
287
  }
250
288
  if (!storageChanges[storageType]) {
@@ -278,7 +316,7 @@ function main(namespace) {
278
316
  return getState.apply(null, arguments);
279
317
  }
280
318
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isArray)(arguments[1])) {
281
- return _listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener.apply(null, arguments);
319
+ return _listeners__WEBPACK_IMPORTED_MODULE_5__.addStateListener.apply(null, arguments);
282
320
  }
283
321
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isObject)(arguments[1])) {
284
322
  return setState.apply(null, arguments);
@@ -288,7 +326,7 @@ function setStorageUtils(storageUtils) {
288
326
  Object.assign(STORAGE, storageUtils);
289
327
  }
290
328
  function addNamespace(namespace, str) {
291
- return `${namespace}${((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isString)(str) && _constants__WEBPACK_IMPORTED_MODULE_2__.NAMESPACE_DELIMITER) || ""}${str || ""}`;
329
+ return `${namespace}${((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isString)(str) && _constants__WEBPACK_IMPORTED_MODULE_3__.NAMESPACE_DELIMITER) || ""}${str || ""}`;
292
330
  }
293
331
  function createStore(_namespace) {
294
332
  const namespace = ((key) => addNamespace(_namespace, key));
@@ -298,8 +336,9 @@ function createStore(_namespace) {
298
336
  get: (newNamespace) => getState(namespace, newNamespace),
299
337
  set: async (changes) => await setState(namespace, changes),
300
338
  reset: (keys) => resetState(namespace, keys),
301
- onChange: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener)(namespace, keys, cb),
302
- removeListener: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.removeStateListener)(namespace, keys, cb),
339
+ onChange: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_5__.addStateListener)(namespace, keys, cb),
340
+ removeListener: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_5__.removeStateListener)(namespace, keys, cb),
341
+ actions: (actions) => (0,_actions__WEBPACK_IMPORTED_MODULE_2__.addStateActions)(namespace, actions),
303
342
  setStorageUtils,
304
343
  onStateChange,
305
344
  });
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see varstor.min.js.LICENSE.txt */
2
- !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Varstor=t():e.Varstor=t()}(this,()=>(()=>{"use strict";var e={"./src/constants.ts"(e,t,n){n.r(t),n.d(t,{NAMESPACE_DELIMITER:()=>r});const r="::"},"./src/helpers.ts"(e,t,n){n.r(t),n.d(t,{filter:()=>p,forEach:()=>d,getParamNames:()=>l,isArray:()=>o,isFunction:()=>i,isObject:()=>a,isString:()=>c,map:()=>f,recreateStructure:()=>E});const r=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,s=/([^\s,]+)/g;function o(e){return"[object Array]"===u(e)}function c(e){return"[object String]"===u(e)}function i(e){return"[object Function]"===u(e)}function a(e){return"[object Object]"===u(e)}function u(e){return Object.prototype.toString.call(e)}function l(e){const t=e.toString().replace(r,"").split("=>")[0],n=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(s);return null===n?[]:n}function f(e,t){const n=Object.entries(e).map(([e,n])=>t(e,n));return 2===n[0]?.length?Object.fromEntries(n):n}function d(e,t){Object.entries(e||{}).forEach(([e,n])=>t(e,n))}function p(e,t){return Object.fromEntries(Object.entries(e||{}).filter(([e,n])=>!0===t(e,n)))}function E(e){let t=e;if(o(e))return t=[],e.forEach(e=>t.push(E(e))),t;if(a(e)){t={};for(let n in e)t[n]=E(e[n]);return t}return t}},"./src/index.ts"(e,t,n){n.r(t),n.d(t,{STATE:()=>a,createStore:()=>j,default:()=>O,getValues:()=>p});var r=n("./src/storage.ts"),s=n("./src/helpers.ts"),o=n("./src/constants.ts"),c=n("./src/validation.ts"),i=n("./src/listeners.ts");const a={},u={};async function l(e,t,n){const r=u.GET_TYPE(n),o=Object.assign({},t),l=(0,s.map)(t,(t,n)=>[e(t),n]);u.IS_AVAILABE(r)&&await u.UPDATE_STATE(l,r),i.LISTENERS[e()]||(i.LISTENERS[e()]=[]);for(const n in t){const t=e(n);c.isValid.Defining(t),a[t]=f(n,e,l[t],o[n],r)}return j(e())}function f(e,t,n,r,o){const c=t(e),i=(0,s.isFunction)(n),u=i?(0,s.getParamNames)(n):[];return u.forEach(e=>{const n=t(e);a[n]||(a[n]={dependants:[],dependencies:[],namespace:t,storageType:o}),a[n].dependants?.push(c)}),{key:e,fullKey:c,value:i?n.apply(null,E(u,t)):n,computeFn:i&&n,dependencies:u,dependants:[],listeners:[],defaultValue:r,storageType:o,namespace:t}}function d(e){return(0,s.filter)(a,(t,{key:n})=>t===e(n))}function p(e){return(0,s.map)(d(e),(e,{key:t,value:n})=>[t,n])}function E(e,t){const n=p(t);return e.map(e=>n[e])}async function S(e){const t={};for(const n in e){const r=a[n].value,s=e[n].newValue;r!==s?(t[n]={newValue:s,prevValue:r},a[n].value=s):t[n]={isSame:!0},y(n,e,t)}await(0,i.runStateChangeListeners)((0,s.filter)(t,(e,t)=>!t.isSame))}function y(e,t,n){a[e].dependants?.forEach(e=>{const{dependencies:r,namespace:s}=a[e];if(!function(e,t,n,r){return e.every(e=>{const s=t(e);return n.includes(s)&&r.includes(s)||!n.includes(s)})}(r,s,Object.keys(t),Object.keys(n))||n[e])return;const o=a[e].value,c=a[e].computeFn?.apply(null,E(r,s));o!==c&&(n[e]={newValue:c,prevValue:o},a[e].value=c,y(e,t,n))})}function g(e,t){return(0,s.isString)(t)?j(t):(0,s.recreateStructure)(p(e))}async function T(e,t){const n={};(0,s.forEach)(t,(t,r)=>{const s=e(t),{storageType:o,computeFn:c}=a[s];c||(n[o]||(n[o]={}),n[o][s]=r)});for(let[e,t]of Object.entries(n))await m(e,t);return j(e())}async function m(e,t){if(u.IS_AVAILABE(e)){if(await u.SET_VALUES(e,t))return}S((0,s.map)(t,(e,t)=>[e,{newValue:t}]))}function A(e){return!arguments[1]||(0,s.isString)(arguments[1])?g.apply(null,arguments):(0,s.isArray)(arguments[1])?i.addStateListener.apply(null,arguments):(0,s.isObject)(arguments[1])?T.apply(null,arguments):void 0}function b(e){Object.assign(u,e)}function j(e){const t=t=>function(e,t){return`${e}${(0,s.isString)(t)&&o.NAMESPACE_DELIMITER||""}${t||""}`}(e,t);return Object.assign(A.bind(null,t),{add:e=>l(t,e,!1),addPersistent:e=>l(t,e,!0),get:e=>g(t,e),set:async e=>await T(t,e),reset:e=>async function(e,t){const n=d(e);return await T(e,(0,s.map)(t?(0,s.filter)(n,(e,{key:n})=>t.includes(n)):n,(e,{key:t,defaultValue:n})=>[t,n])),j(e())}(t,e),onChange:(e,n)=>(0,i.addStateListener)(t,e,n),removeListener:(e,n)=>(0,i.removeStateListener)(t,e,n),setStorageUtils:b,onStateChange:S})}b(r.default);const O=j("")},"./src/listeners.ts"(e,t,n){n.r(t),n.d(t,{LISTENERS:()=>c,addStateListener:()=>a,removeStateListener:()=>u,runStateChangeListeners:()=>i});var r=n("./src/index.ts"),s=n("./src/constants.ts"),o=n("./src/helpers.ts");const c={};async function i(e){if(Object.keys(e).length){const{namespace:t}=r.STATE[Object.keys(e)[0]],n=(0,r.getValues)(t);for(let[t,s]of Object.entries(e)){const{listeners:e,key:o}=r.STATE[t];for(const t of e)await t([o],n,s)}const i=(0,o.map)(e,e=>e.slice(s.NAMESPACE_DELIMITER.length));for(const r of c[t()])await r(i,n,(0,o.map)(e,(e,t)=>[e.slice(s.NAMESPACE_DELIMITER.length),t]))}}function a(e,t,n){return(0,o.isFunction)(t)?(c[e()].push(t),(0,r.createStore)(e())):(t.forEach(t=>r.STATE[e(t)].listeners?.push(n)),(0,r.createStore)(e()))}function u(e,t,n){if((0,o.isFunction)(t)){const n=c[e()].findIndex(e=>e===t);return c[e()].splice(n,1),(0,r.createStore)(e())}return t.forEach(t=>{const s=r.STATE[e(t)].listeners,o=s?.findIndex(e=>e===n);s?.splice(o,1)}),(0,r.createStore)(e())}},"./src/storage.ts"(e,t,n){n.r(t),n.d(t,{default:()=>r});const r={GET_TYPE:function(e){return e?"localStorage":""},IS_AVAILABE:function(e){return!!e},UPDATE_STATE:async function(e){const t={};for(const n in e){const e=localStorage.getItem(n);null!==e&&(t[n]=e)}return Object.assign(e,t)},SET_VALUES:async function(e,t){for(let[e,n]of Object.entries(t))localStorage.setItem(e,n);return!1}}},"./src/validation.ts"(e,t,n){n.r(t),n.d(t,{isValid:()=>c});var r=n("./src/index.ts"),s=n("./src/constants.ts");function o(e){const t=e.split(s.NAMESPACE_DELIMITER);return[t.slice(-1)[0],t.join(s.NAMESPACE_DELIMITER)]}const c={Setting:e=>{if(!r.STATE[e]){const[t,n]=o(e);throw new Error(`Setting "${t}" key in "${n}" namespace. DOES NOT EXIST`)}return!0},Defining:e=>{if(r.STATE[e]){const[t,n]=o(e);throw new Error(`Redefining "${t}" key in "${n}" namespace. ALREADY DEFINED`)}return!0}}}};const t={};function n(r){const s=t[r];if(void 0!==s)return s.exports;const o=t[r]={exports:{}};if(!(r in e)){delete t[r];const e=new Error("Cannot find module '"+r+"'");throw e.code="MODULE_NOT_FOUND",e}return e[r](o,o.exports,n),o.exports}n.d=(e,t)=>{if(Array.isArray(t))for(var r=0;r<t.length;){var s=t[r++],o=t[r++];n.o(e,s)?0===o&&r++:0===o?Object.defineProperty(e,s,{enumerable:!0,value:t[r++]}):Object.defineProperty(e,s,{enumerable:!0,get:o})}else for(var s in t)n.o(t,s)&&!n.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};let r=n("./src/index.ts");return r=r.default,r})());
2
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Varstor=t():e.Varstor=t()}(this,()=>(()=>{"use strict";var e={"./src/actions.ts"(e,t,n){n.r(t),n.d(t,{addStateActions:()=>s});var r=n("./src/index.ts");function s(e,t){const n={get:r.getState.bind(null,e),set:r.setState.bind(null,e),reset:r.resetState.bind(null,e)};for(let[s,c]of Object.entries(t))r.STATE[e(s)]={key:s,namespace:e,value:c.bind(null,n),isAction:!0,listeners:[]}}},"./src/constants.ts"(e,t,n){n.r(t),n.d(t,{NAMESPACE_DELIMITER:()=>r});const r="::"},"./src/helpers.ts"(e,t,n){n.r(t),n.d(t,{filter:()=>p,forEach:()=>d,getParamNames:()=>l,isArray:()=>c,isFunction:()=>i,isObject:()=>a,isString:()=>o,map:()=>f,recreateStructure:()=>S});const r=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,s=/([^\s,]+)/g;function c(e){return"[object Array]"===u(e)}function o(e){return"[object String]"===u(e)}function i(e){return"[object Function]"===u(e)}function a(e){return"[object Object]"===u(e)}function u(e){return Object.prototype.toString.call(e)}function l(e){const t=e.toString().replace(r,"").split("=>")[0],n=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(s);return null===n?[]:n}function f(e,t){const n=Object.entries(e).map(([e,n])=>t(e,n));return 2===n[0]?.length?Object.fromEntries(n):n}function d(e,t){Object.entries(e||{}).forEach(([e,n])=>t(e,n))}function p(e,t){return Object.fromEntries(Object.entries(e||{}).filter(([e,n])=>!0===t(e,n)))}function S(e){let t=e;if(c(e))return t=[],e.forEach(e=>t.push(S(e))),t;if(a(e)){t={};for(let n in e)t[n]=S(e[n]);return t}return t}},"./src/index.ts"(e,t,n){n.r(t),n.d(t,{STATE:()=>u,createStore:()=>h,default:()=>v,getState:()=>A,getValues:()=>S,resetState:()=>m,setState:()=>T,setupValue:()=>d});var r=n("./src/storage.ts"),s=n("./src/helpers.ts"),c=n("./src/actions.ts"),o=n("./src/constants.ts"),i=n("./src/validation.ts"),a=n("./src/listeners.ts");const u={},l={};async function f(e,t,n){const r=l.GET_TYPE(n),c=Object.assign({},t),o=(0,s.map)(t,(t,n)=>[e(t),n]);l.IS_AVAILABE(r)&&await l.UPDATE_STATE(o,r),a.LISTENERS[e()]||(a.LISTENERS[e()]=[]);for(const n in t){const t=e(n);i.isValid.Defining(t),u[t]=d(n,e,o[t],c[n],r)}return h(e())}function d(e,t,n,r,c){const o=t(e),i=(0,s.isFunction)(n),a=i?(0,s.getParamNames)(n):[];return a.forEach(e=>{const n=t(e);u[n]||(u[n]={dependants:[],dependencies:[],namespace:t,storageType:c}),u[n].dependants?.push(o)}),{key:e,fullKey:o,value:i?n.apply(null,E(a,t)):n,computeFn:i&&n,dependencies:a,dependants:[],listeners:[],defaultValue:r,storageType:c,namespace:t}}function p(e){return(0,s.filter)(u,(t,{key:n})=>t===e(n))}function S(e){return(0,s.map)(p(e),(e,{key:t,value:n})=>[t,n])}function E(e,t){const n=S(t);return e.map(e=>n[e])}async function g(e){const t={};for(const n in e){const r=u[n].value,s=e[n].newValue;r!==s?(t[n]={newValue:s,prevValue:r},u[n].value=s):t[n]={isSame:!0},y(n,e,t)}await(0,a.runStateChangeListeners)((0,s.filter)(t,(e,t)=>!t.isSame))}function y(e,t,n){u[e].dependants?.forEach(e=>{const{dependencies:r,namespace:s}=u[e];if(!function(e,t,n,r){return e.every(e=>{const s=t(e);return n.includes(s)&&r.includes(s)||!n.includes(s)})}(r,s,Object.keys(t),Object.keys(n))||n[e])return;const c=u[e].value,o=u[e].computeFn?.apply(null,E(r,s));c!==o&&(n[e]={newValue:o,prevValue:c},u[e].value=o,y(e,t,n))})}function A(e,t){return(0,s.isString)(t)?h(t):(0,s.recreateStructure)(S(e))}async function T(e,t){const n={};(0,s.forEach)(t,(t,r)=>{const s=e(t),{storageType:c,computeFn:o,isAction:i}=u[s];o||i||(n[c]||(n[c]={}),n[c][s]=r)});for(let[e,t]of Object.entries(n))await b(e,t);return h(e())}async function b(e,t){if(l.IS_AVAILABE(e)){if(await l.SET_VALUES(e,t))return}g((0,s.map)(t,(e,t)=>[e,{newValue:t}]))}async function m(e,t){const n=p(e);return await T(e,(0,s.map)(t?(0,s.filter)(n,(e,{key:n})=>t.includes(n)):n,(e,{key:t,defaultValue:n})=>[t,n])),h(e())}function j(e){return!arguments[1]||(0,s.isString)(arguments[1])?A.apply(null,arguments):(0,s.isArray)(arguments[1])?a.addStateListener.apply(null,arguments):(0,s.isObject)(arguments[1])?T.apply(null,arguments):void 0}function O(e){Object.assign(l,e)}function h(e){const t=t=>function(e,t){return`${e}${(0,s.isString)(t)&&o.NAMESPACE_DELIMITER||""}${t||""}`}(e,t);return Object.assign(j.bind(null,t),{add:e=>f(t,e,!1),addPersistent:e=>f(t,e,!0),get:e=>A(t,e),set:async e=>await T(t,e),reset:e=>m(t,e),onChange:(e,n)=>(0,a.addStateListener)(t,e,n),removeListener:(e,n)=>(0,a.removeStateListener)(t,e,n),actions:e=>(0,c.addStateActions)(t,e),setStorageUtils:O,onStateChange:g})}O(r.default);const v=h("")},"./src/listeners.ts"(e,t,n){n.r(t),n.d(t,{LISTENERS:()=>o,addStateListener:()=>a,removeStateListener:()=>u,runStateChangeListeners:()=>i});var r=n("./src/index.ts"),s=n("./src/constants.ts"),c=n("./src/helpers.ts");const o={};async function i(e){if(Object.keys(e).length){const{namespace:t}=r.STATE[Object.keys(e)[0]],n=(0,r.getValues)(t);for(let[t,s]of Object.entries(e)){const{listeners:e,key:c}=r.STATE[t];for(const t of e)await t([c],n,s)}const i=(0,c.map)(e,e=>e.slice(s.NAMESPACE_DELIMITER.length));for(const r of o[t()])await r(i,n,(0,c.map)(e,(e,t)=>[e.slice(s.NAMESPACE_DELIMITER.length),t]))}}function a(e,t,n){return(0,c.isFunction)(t)?(o[e()].push(t),(0,r.createStore)(e())):(t.forEach(t=>r.STATE[e(t)].listeners?.push(n)),(0,r.createStore)(e()))}function u(e,t,n){if((0,c.isFunction)(t)){const n=o[e()].findIndex(e=>e===t);return o[e()].splice(n,1),(0,r.createStore)(e())}return t.forEach(t=>{const s=r.STATE[e(t)].listeners,c=s?.findIndex(e=>e===n);s?.splice(c,1)}),(0,r.createStore)(e())}},"./src/storage.ts"(e,t,n){n.r(t),n.d(t,{default:()=>r});const r={GET_TYPE:function(e){return e?"localStorage":""},IS_AVAILABE:function(e){return!!e},UPDATE_STATE:async function(e){const t={};for(const n in e){const e=localStorage.getItem(n);null!==e&&(t[n]=e)}return Object.assign(e,t)},SET_VALUES:async function(e,t){for(let[e,n]of Object.entries(t))localStorage.setItem(e,n);return!1}}},"./src/validation.ts"(e,t,n){n.r(t),n.d(t,{isValid:()=>o});var r=n("./src/index.ts"),s=n("./src/constants.ts");function c(e){const t=e.split(s.NAMESPACE_DELIMITER);return[t.slice(-1)[0],t.join(s.NAMESPACE_DELIMITER)]}const o={Setting:e=>{if(!r.STATE[e]){const[t,n]=c(e);throw new Error(`Setting "${t}" key in "${n}" namespace. DOES NOT EXIST`)}return!0},Defining:e=>{if(r.STATE[e]){const[t,n]=c(e);throw new Error(`Redefining "${t}" key in "${n}" namespace. ALREADY DEFINED`)}return!0}}}};const t={};function n(r){const s=t[r];if(void 0!==s)return s.exports;const c=t[r]={exports:{}};if(!(r in e)){delete t[r];const e=new Error("Cannot find module '"+r+"'");throw e.code="MODULE_NOT_FOUND",e}return e[r](c,c.exports,n),c.exports}n.d=(e,t)=>{if(Array.isArray(t))for(var r=0;r<t.length;){var s=t[r++],c=t[r++];n.o(e,s)?0===c&&r++:0===c?Object.defineProperty(e,s,{enumerable:!0,value:t[r++]}):Object.defineProperty(e,s,{enumerable:!0,get:c})}else for(var s in t)n.o(t,s)&&!n.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};let r=n("./src/index.ts");return r=r.default,r})());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "varstor",
3
- "version": "0.6.62",
3
+ "version": "0.6.63",
4
4
  "description": "State manager for web applications and webextensions, employing reactivity, wrapping, and uniting the usage of different storages' values and common variables into a simple universal interface",
5
5
  "license": "MIT",
6
6
  "author": "Igor Morozov <ismorozs@gmail.com>",
package/src/actions.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { STATE, getState, setState, resetState } from ".";
2
+
3
+ export function addStateActions(namespace: INamespace, actions: IStateActions) {
4
+ const stateAcessor = {
5
+ get: getState.bind(null, namespace),
6
+ set: setState.bind(null, namespace),
7
+ reset: resetState.bind(null, namespace),
8
+ };
9
+
10
+ for (let [actionName, actionFn] of Object.entries(actions)) {
11
+ STATE[namespace(actionName)] = {
12
+ key: actionName,
13
+ namespace,
14
+ value: actionFn.bind(null, stateAcessor),
15
+ isAction: true,
16
+ listeners: [],
17
+ };
18
+ }
19
+ }
package/src/index.ts CHANGED
@@ -12,6 +12,8 @@ import {
12
12
  forEach,
13
13
  } from "./helpers";
14
14
 
15
+ import { addStateActions } from "./actions";
16
+
15
17
  import { NAMESPACE_DELIMITER } from "./constants";
16
18
 
17
19
  import { isValid } from "./validation";
@@ -62,7 +64,7 @@ async function addState(
62
64
  return createStore(namespace());
63
65
  }
64
66
 
65
- function setupValue(
67
+ export function setupValue(
66
68
  key: string,
67
69
  namespace: INamespace,
68
70
  value: unknown,
@@ -153,7 +155,7 @@ function updateDependencies(
153
155
 
154
156
  if (
155
157
  !isEveryDependencyReady(
156
- dependencies,
158
+ dependencies!,
157
159
  namespace,
158
160
  Object.keys(changes),
159
161
  Object.keys(realChanges),
@@ -166,7 +168,7 @@ function updateDependencies(
166
168
  const prevValue = STATE[name].value;
167
169
  const newValue = (STATE[name].computeFn as IComputeFunction)?.apply(
168
170
  null,
169
- getArguments(dependencies, namespace),
171
+ getArguments(dependencies!, namespace),
170
172
  );
171
173
 
172
174
  if (prevValue !== newValue) {
@@ -192,7 +194,7 @@ function isEveryDependencyReady(
192
194
  });
193
195
  }
194
196
 
195
- function getState(namespace: INamespace, arg: string) {
197
+ export function getState(namespace: INamespace, arg: string) {
196
198
  if (isString(arg)) {
197
199
  return createStore(arg);
198
200
  }
@@ -200,7 +202,7 @@ function getState(namespace: INamespace, arg: string) {
200
202
  return recreateStructure(getValues(namespace));
201
203
  }
202
204
 
203
- async function setState(
205
+ export async function setState(
204
206
  namespace: INamespace,
205
207
  changes: Record<string, unknown>,
206
208
  ): Promise<unknown> {
@@ -208,17 +210,17 @@ async function setState(
208
210
 
209
211
  forEach(changes, (k, v) => {
210
212
  const fullKey = namespace(k);
211
- const { storageType, computeFn } = STATE[fullKey];
213
+ const { storageType, computeFn, isAction } = STATE[fullKey];
212
214
 
213
- if (computeFn) {
215
+ if (computeFn || isAction) {
214
216
  return;
215
217
  }
216
218
 
217
- if (!storageChanges[storageType]) {
218
- storageChanges[storageType] = {};
219
+ if (!storageChanges[storageType!]) {
220
+ storageChanges[storageType!] = {};
219
221
  }
220
222
 
221
- storageChanges[storageType][fullKey] = v;
223
+ storageChanges[storageType!][fullKey] = v;
222
224
  });
223
225
 
224
226
  for (let [storageType, changes] of Object.entries(storageChanges)) {
@@ -244,7 +246,7 @@ async function setValues(
244
246
  );
245
247
  }
246
248
 
247
- async function resetState(namespace: INamespace, keys?: string[]) {
249
+ export async function resetState(namespace: INamespace, keys?: string[]) {
248
250
  const namespaceState = getNamespaceState(namespace);
249
251
 
250
252
  await setState(
@@ -303,6 +305,7 @@ export function createStore(_namespace: string) {
303
305
  addStateListener(namespace, keys, cb),
304
306
  removeListener: (keys: string[], cb: () => {}) =>
305
307
  removeStateListener(namespace, keys, cb),
308
+ actions: (actions: IStateActions) => addStateActions(namespace, actions),
306
309
  setStorageUtils,
307
310
  onStateChange,
308
311
  });
package/src/types.d.ts CHANGED
@@ -7,9 +7,10 @@ type IValue = {
7
7
  fullKey?: string;
8
8
  value?: any;
9
9
  computeFn?: boolean | IComputeFunction;
10
- dependencies: string[];
11
- dependants: string[];
12
- storageType: string;
10
+ isAction?: boolean;
11
+ dependencies?: string[];
12
+ dependants?: string[];
13
+ storageType?: string;
13
14
  listeners?: any[];
14
15
  defaultValue?: any;
15
16
  namespace: INamespace;
@@ -37,3 +38,7 @@ type IStateListener = (
37
38
  ) => {};
38
39
 
39
40
  type IStateListeners = Record<string, IStateListener[]>;
41
+
42
+ type IStateAction = (mutator: IStateMutator, args: any[]) => void;
43
+
44
+ type IStateActions = Record<string, IStateAction>;