varstor 0.6.64 → 0.6.65

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
@@ -23,7 +23,7 @@ in your script file.
23
23
  [1.1 Creation ```.add()```/```.addPersistent()```](#creation)
24
24
  [1.2 Dynamic reevaluation (```ReactiveFunction```)](#reactivefunction)
25
25
  [1.3 Accessing ```.get()```](#accessing)
26
- [1.4 Mutating ```.set()```/```.reset()```](#mutating)
26
+ [1.4 Mutating ```.set()```/```.reset()```/```.changes.*()```](#mutating)
27
27
  [1.5 Listening ```.onChange()```/```.removeListener()```](#listening)
28
28
  [1.6 Data encapsulation ```.actions()```](#actions)
29
29
  [1.7 Namespacing ```.get(Namespace)```](#namespacing)
@@ -32,16 +32,18 @@ in your script file.
32
32
  3. [Example](#example)
33
33
 
34
34
  ## Usage <a name="overview"></a>
35
- The library object features the following methods:
35
+ The library object features the following methods and properties:
36
36
  ```js
37
37
  .add ()
38
38
  .addPersistent ()
39
39
  .get ()
40
40
  .set ()
41
41
  .reset ()
42
+ .changes {}
42
43
  .onChange ()
43
44
  .removeListener ()
44
45
  .actions ()
46
+ .namespace () // just returns the string value of the current namespace
45
47
  ```
46
48
 
47
49
  ## Creation ```.add()```/```.addPersistent()``` <a name="creation"></a>
@@ -92,7 +94,7 @@ Where:
92
94
 
93
95
 
94
96
 
95
- ## Mutating ```.set()```/```.reset()``` <a name="mutating"></a>
97
+ ## Mutating ```.set()```/```.reset()```/```.changes.*()``` <a name="mutating"></a>
96
98
  Values are mutated with:
97
99
  ```js
98
100
  async Varstor.set(
@@ -102,13 +104,22 @@ async Varstor.set(
102
104
  }
103
105
  ) => Varstor
104
106
  ```
105
-
107
+ \
106
108
  To reset values back to defaults:
107
109
  ```js
108
110
  async Varstor.reset(Keys []) => Varstor
109
111
  ```
110
112
  Where:
111
113
  ```Keys[]``` (optional) - array of keys to return to default values. If omitted all values will be returned to defaults.
114
+ \
115
+ For more control over the timing of state changes in the namespace, use ```.changes {}``` methods collection.
116
+ ```js
117
+ Varstor.changes.add(KeysValues {}) // => adds pending changes in the current namespace
118
+ Varstor.changes.reset(Keys []) // => adds pending changes that will reset some of the keys
119
+ Varstor.changes.get() // => gets pending changes in the current namespace
120
+ Varstor.changes.flush() // => returns and then empties the pending changes object
121
+ Varstor.changes.commit() // => actually commits all accumulated pending changes in the namespace
122
+ ```
112
123
 
113
124
  > [!WARNING]
114
125
  > Values are mutated asynchronously; don't assume the script will recognize the change immediately on the next line. Instead, ```await``` or make use of ```onChange``` listeners!
@@ -120,18 +131,21 @@ To listen and react to state changes:
120
131
  ```js
121
132
  Varstor.onChange(
122
133
  Keys[],
123
- ChangeCallback(ChangedKeys [], allValues {}, PreviousValues {}) => void
134
+ ChangeCallback(ChangedKeys [], Varstor) => void
124
135
  ) => Varstor
125
136
  ```
126
137
  Where:
127
138
  ```Keys[]``` (optional) - array of keys of the state in the current namespace that you want to listen to. If omitted, ```ChangeCallback``` will run on any value change in the namespace.
128
- ```ChangeCallback``` - function to run when a change happens
139
+
129
140
 
141
+ ```ChangeCallback``` - a function to run when the change happens. Takes ```ChangedKeys[]``` array of keys that have been changed as the first argument, and a ```Varstor``` instance as the second.
142
+ \
143
+ \
130
144
  To remove the listener:
131
145
  ```js
132
146
  Varstor.removeListener(
133
147
  Keys[],
134
- ChangeCallback(ChangedKeys [], allValues {}, PreviousValues {}) => void
148
+ ChangeCallback(ChangedKeys [], Varstor) => void
135
149
  ) => Varstor
136
150
  ```
137
151
  the same parameter usage.
@@ -170,7 +184,7 @@ which will return a new instance of ```Varstor``` with the specified ```Namespac
170
184
 
171
185
 
172
186
  ## Method chaining <a name="chaining"></a>
173
- Methods ```.add```, ```.addPersistent```, ```.set()```, ```.reset()```, ```onChange```, and ```removeListener``` all return a new instance of ```Varstor``` with the same namespace, so method chaining is possible.
187
+ Methods ```.add```, ```.addPersistent```, ```.set()```, ```.reset()```, ```.onChange()```, and ```.removeListener()``` all return a new instance of ```Varstor``` with the same namespace, so method chaining is possible.
174
188
 
175
189
 
176
190
  ## Shortcuts <a name="shortcuts"></a>
@@ -179,13 +193,14 @@ The library/namespace object itself can be called with different types of argume
179
193
  Varstor() -> Varstor.get()
180
194
  Varstor(String namespace) -> Varstor.get(namespace)
181
195
  Varstor({ key: value }) -> Varstor.set({ key: value })
182
- Varstor([], () => {}) -> Varstor.onChange([], () => {})
196
+ Varstor([], () => {}) -> Varstor.onChange([], () => {})
197
+ Varstor(() => {}) -> Varstor.onChange(() => {})
183
198
  ```
184
199
 
185
200
  ## Example <a name="example"></a>
186
201
  ```js
187
- function onChange(changes, values, data) {
188
- console.log("onChange", changes, values, data);
202
+ function onChange(changes, store) {
203
+ console.log("onChange", store.get());
189
204
  }
190
205
 
191
206
  await Varstor.add({
@@ -242,4 +257,21 @@ logValues(); // x: 10, y: 3, z: 3
242
257
  await newNamespace({ z: 110 });
243
258
 
244
259
  console.log(Varstor("new namespace").get()); // {x: 10, y: 3, z: 110, logValues: ƒ, multiplyX: ƒ, …}
260
+
261
+ const thirdNamespace = Varstor("third namespace");
262
+
263
+ thirdNamespace.add({
264
+ phrase: "Hello",
265
+ to: "world",
266
+ });
267
+
268
+ thirdNamespace.changes.add({ phrase: "Greetings" });
269
+ thirdNamespace.changes.add({ to: "you" });
270
+
271
+ console.log(thirdNamespace.get()) // {phrase: 'Hello', to: 'world'}
272
+
273
+ thirdNamespace.changes.commit();
274
+
275
+ console.log(thirdNamespace.get()) // {phrase: 'Greetings', to: 'you'}
276
+
245
277
  ```
@@ -25,16 +25,11 @@ __webpack_require__.r(__webpack_exports__);
25
25
  /* harmony import */ var ___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! . */ "./src/index.ts");
26
26
 
27
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)) {
28
+ for (const [actionName, actionFn] of Object.entries(actions)) {
34
29
  ___WEBPACK_IMPORTED_MODULE_0__.STATE[namespace(actionName)] = {
35
30
  key: actionName,
36
31
  namespace,
37
- value: actionFn.bind(null, stateAcessor),
32
+ value: actionFn.bind(null, (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace())),
38
33
  isAction: true,
39
34
  listeners: [],
40
35
  };
@@ -157,6 +152,7 @@ function uid() {
157
152
  __webpack_require__.r(__webpack_exports__);
158
153
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
159
154
  /* harmony export */ STATE: () => (/* binding */ STATE),
155
+ /* harmony export */ createPendingChanges: () => (/* binding */ createPendingChanges),
160
156
  /* harmony export */ createStore: () => (/* binding */ createStore),
161
157
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
162
158
  /* harmony export */ getState: () => (/* binding */ getState),
@@ -177,7 +173,8 @@ __webpack_require__.r(__webpack_exports__);
177
173
 
178
174
 
179
175
  const STATE = {};
180
- const WAITING_CHANGES = {};
176
+ const STATE_CHANGED_PIECES = {};
177
+ const STATE_PENDING_CHANGES = {};
181
178
  const STORAGE = {};
182
179
  setStorageUtils(_storage__WEBPACK_IMPORTED_MODULE_0__["default"]);
183
180
  async function addState(namespace, initialState, isPersistent) {
@@ -187,9 +184,6 @@ async function addState(namespace, initialState, isPersistent) {
187
184
  if (STORAGE.IS_AVAILABE(storageType)) {
188
185
  await STORAGE.UPDATE_STATE(values, storageType);
189
186
  }
190
- if (!_listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()]) {
191
- _listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()] = [];
192
- }
193
187
  for (const key in initialState) {
194
188
  const fullKey = namespace(key);
195
189
  STATE[fullKey] = setupValue(key, namespace, values[fullKey], defaultValues[key], storageType);
@@ -243,7 +237,7 @@ function getArguments(dependencies, namespace) {
243
237
  return dependencies.map((name) => values[name]);
244
238
  }
245
239
  async function joinStateChanges(changesPiece) {
246
- for (const [updateId, { storageTypes, readyStorageTypes, changes },] of Object.entries(WAITING_CHANGES)) {
240
+ for (const [updateId, { storageTypes, readyStorageTypes, changes },] of Object.entries(STATE_CHANGED_PIECES)) {
247
241
  if (changesPiece[updateId]) {
248
242
  const storageType = changesPiece[updateId].newValue;
249
243
  readyStorageTypes[storageType] = true;
@@ -257,7 +251,7 @@ async function joinStateChanges(changesPiece) {
257
251
  return;
258
252
  }
259
253
  }
260
- delete WAITING_CHANGES[updateId];
254
+ delete STATE_CHANGED_PIECES[updateId];
261
255
  await onStateChange(changes);
262
256
  }
263
257
  }
@@ -323,7 +317,7 @@ async function setState(namespace, changes) {
323
317
  storageTypes[storageType] = true;
324
318
  storageChanges[storageType][fullKey] = v;
325
319
  });
326
- WAITING_CHANGES[updateId] = {
320
+ STATE_CHANGED_PIECES[updateId] = {
327
321
  storageTypes,
328
322
  readyStorageTypes: {},
329
323
  changes: {},
@@ -343,17 +337,34 @@ async function setValues(storageType, changes) {
343
337
  joinStateChanges((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(changes, (k, newValue) => [k, { newValue }]));
344
338
  }
345
339
  async function resetState(namespace, keys) {
340
+ await setState(namespace, getDefaultValues(namespace, keys));
341
+ return createStore(namespace());
342
+ }
343
+ function getDefaultValues(namespace, keys) {
346
344
  const namespaceState = getNamespaceState(namespace);
347
- await setState(namespace, (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(keys
345
+ return (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(keys
348
346
  ? (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(namespaceState, (k, { key }) => keys.includes(key))
349
- : namespaceState, (k, { key, defaultValue }) => [key, defaultValue]));
350
- return createStore(namespace());
347
+ : namespaceState, (k, { key, defaultValue }) => [key, defaultValue]);
348
+ }
349
+ function createPendingChanges(namespace) {
350
+ const flush = () => {
351
+ const changes = STATE_PENDING_CHANGES[namespace()];
352
+ STATE_PENDING_CHANGES[namespace()] = {};
353
+ return changes;
354
+ };
355
+ return {
356
+ add: (changes) => Object.assign(STATE_PENDING_CHANGES[namespace()], changes),
357
+ reset: (keys) => Object.assign(STATE_PENDING_CHANGES[namespace()], getDefaultValues(namespace, keys)),
358
+ get: () => STATE_PENDING_CHANGES[namespace()],
359
+ flush,
360
+ commit: () => setState(namespace, flush()),
361
+ };
351
362
  }
352
363
  function main(namespace) {
353
364
  if (!arguments[1] || (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isString)(arguments[1])) {
354
365
  return getState.apply(null, arguments);
355
366
  }
356
- if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isArray)(arguments[1])) {
367
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isArray)(arguments[1]) || (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isFunction)(arguments[1]) || (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isAsyncFunction)(arguments[1])) {
357
368
  return _listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener.apply(null, arguments);
358
369
  }
359
370
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isObject)(arguments[1])) {
@@ -368,12 +379,19 @@ function addNamespace(namespace, str) {
368
379
  }
369
380
  function createStore(_namespace) {
370
381
  const namespace = ((key) => addNamespace(_namespace, key));
382
+ if (!STATE_PENDING_CHANGES[namespace()]) {
383
+ STATE_PENDING_CHANGES[namespace()] = {};
384
+ }
385
+ if (!_listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()]) {
386
+ _listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()] = [];
387
+ }
371
388
  return Object.assign(main.bind(null, namespace), {
372
389
  add: (state) => addState(namespace, state, false),
373
390
  addPersistent: (state) => addState(namespace, state, true),
374
391
  get: (newNamespace) => getState(namespace, newNamespace),
375
392
  set: async (changes) => await setState(namespace, changes),
376
393
  reset: (keys) => resetState(namespace, keys),
394
+ changes: createPendingChanges(namespace),
377
395
  onChange: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener)(namespace, keys, cb),
378
396
  removeListener: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.removeStateListener)(namespace, keys, cb),
379
397
  actions: (actions) => (0,_actions__WEBPACK_IMPORTED_MODULE_2__.addStateActions)(namespace, actions),
@@ -411,11 +429,10 @@ const LISTENERS = {};
411
429
  async function runStateChangeListeners(realChanges) {
412
430
  if (Object.keys(realChanges).length) {
413
431
  const { namespace } = ___WEBPACK_IMPORTED_MODULE_0__.STATE[Object.keys(realChanges)[0]];
414
- const stateValues = (0,___WEBPACK_IMPORTED_MODULE_0__.getValues)(namespace);
415
- for (let [changeKey, change] of Object.entries(realChanges)) {
432
+ for (const [changeKey] of Object.entries(realChanges)) {
416
433
  const { listeners, key } = ___WEBPACK_IMPORTED_MODULE_0__.STATE[changeKey];
417
434
  for (const cb of listeners) {
418
- const fn = cb.bind(null, [key], stateValues, change);
435
+ const fn = cb.bind(null, [key], (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace()));
419
436
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(cb)) {
420
437
  await fn();
421
438
  }
@@ -427,10 +444,7 @@ async function runStateChangeListeners(realChanges) {
427
444
  const namespaceLength = `${namespace()}${_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER}`.length;
428
445
  const readableKeys = (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k) => k.slice(namespaceLength));
429
446
  for (const cb of LISTENERS[namespace()]) {
430
- const fn = cb.bind(null, readableKeys, stateValues, (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k, v) => [
431
- k.slice(namespaceLength),
432
- v,
433
- ]));
447
+ const fn = cb.bind(null, readableKeys, (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace()));
434
448
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(cb)) {
435
449
  await fn();
436
450
  }
@@ -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/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:()=>d,forEach:()=>u,getParamNames:()=>l,isArray:()=>a,isAsyncFunction:()=>g,isFunction:()=>i,isObject:()=>m,isString:()=>o,map:()=>A,recreateStructure:()=>f,uid:()=>x});const t=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,n=/([^\s,]+)/g;function a(e){return"[object Array]"===c(e)}function o(e){return"[object String]"===c(e)}function i(e){return"[object Function]"===c(e)}function g(e){return"[object AsyncFunction]"===c(e)}function m(e){return"[object Object]"===c(e)}function c(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 A(e,r){const s=Object.entries(e).map(([e,s])=>r(e,s));return 2===s[0]?.length?Object.fromEntries(s):s}function u(e,r){Object.entries(e||{}).forEach(([e,s])=>r(e,s))}function d(e,r){return Object.fromEntries(Object.entries(e||{}).filter(([e,s])=>!0===r(e,s)))}function f(e){let r=e;if(a(e))return r=[],e.forEach(e=>r.push(f(e))),r;if(m(e)){r={};for(let s in e)r[s]=f(e[s]);return r}return r}function x(){return Date.now().toString(36)+Math.random().toString(36).substr(2)}},"./src/index.ts"(e,r,s){"use strict";s.r(r),s.d(r,{STATE:()=>g,createStore:()=>v,default:()=>k,getState:()=>y,getValues:()=>d,joinStateChanges:()=>x,resetState:()=>E,setState:()=>h,setupValue:()=>A});var t=s("./src/storage.ts"),n=s("./src/helpers.ts"),a=s("./src/actions.ts"),o=s("./src/constants.ts"),i=s("./src/listeners.ts");const g={},m={},c={};async function l(e,r,s){const t=c.GET_TYPE(s),a=Object.assign({},r),o=(0,n.map)(r,(r,s)=>[e(r),s]);c.IS_AVAILABE(t)&&await c.UPDATE_STATE(o,t),i.LISTENERS[e()]||(i.LISTENERS[e()]=[]);for(const s in r){const r=e(s);g[r]=A(s,e,o[r],a[s],t)}return v(e())}function A(e,r,s,t,a){const o=r(e),i=(0,n.isFunction)(s),m=i?(0,n.getParamNames)(s):[];return m.forEach(e=>{const s=r(e);g[s]||(g[s]={dependants:[],dependencies:[],namespace:r,storageType:a}),g[s].dependants?.push(o)}),{key:e,fullKey:o,value:i?s.apply(null,f(m,r)):s,computeFn:i&&s,dependencies:m,dependants:[],listeners:[],defaultValue:t,storageType:a,namespace:r}}function u(e){return(0,n.filter)(g,(r,{key:s})=>r===e(s))}function d(e){return(0,n.map)(u(e),(e,{key:r,value:s})=>[r,s])}function f(e,r){const s=d(r);return e.map(e=>s[e])}async function x(e){for(const[r,{storageTypes:s,readyStorageTypes:t,changes:n}]of Object.entries(m))if(e[r]){const a=e[r].newValue;t[a]=!0,delete e[r],Object.assign(n,e),c.IS_AVAILABE(a)&&c.REMOVE_KEY(a,r);for(const e in s)if(!t[e])return;delete m[r],await p(n)}}async function p(e){const r={};for(const s in e){const t=g[s].value,n=e[s].newValue;t!==n?(r[s]={newValue:n,prevValue:t},g[s].value=n):r[s]={isSame:!0},b(s,e,r)}await(0,i.runStateChangeListeners)((0,n.filter)(r,(e,r)=>!r.isSame))}function b(e,r,s){g[e].dependants?.forEach(e=>{const{dependencies:t,namespace:n}=g[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=g[e].value,o=g[e].computeFn?.apply(null,f(t,n));a!==o&&(s[e]={newValue:o,prevValue:a},g[e].value=o,b(e,r,s))})}function y(e,r){return(0,n.isString)(r)?v(r):(0,n.recreateStructure)(d(e))}async function h(e,r){const s={},t=(0,n.uid)(),a={};(0,n.forEach)(r,(r,t)=>{const n=e(r),{storageType:o,computeFn:i,isAction:m}=g[n];i||m||(s[o]||(s[o]={}),a[o]=!0,s[o][n]=t)}),m[t]={storageTypes:a,readyStorageTypes:{},changes:{}};for(let[e,r]of Object.entries(s))await S(e,{...r,[t]:e});return v(e())}async function S(e,r){if(c.IS_AVAILABE(e)){if(await c.SET_VALUES(e,r))return}x((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])),v(e())}function w(e){return!arguments[1]||(0,n.isString)(arguments[1])?y.apply(null,arguments):(0,n.isArray)(arguments[1])?i.addStateListener.apply(null,arguments):(0,n.isObject)(arguments[1])?h.apply(null,arguments):void 0}function T(e){Object.assign(c,e)}function v(e){const r=r=>function(e,r){return`${e}${(0,n.isString)(r)&&o.NAMESPACE_DELIMITER||""}${r||""}`}(e,r);return Object.assign(w.bind(null,r),{add:e=>l(r,e,!1),addPersistent:e=>l(r,e,!0),get:e=>y(r,e),set:async e=>await h(r,e),reset:e=>E(r,e),onChange:(e,s)=>(0,i.addStateListener)(r,e,s),removeListener:(e,s)=>(0,i.removeStateListener)(r,e,s),actions:e=>(0,a.addStateActions)(r,e),setStorageUtils:T,joinStateChanges:x,namespace:r})}T(t.default);const k=v("")},"./src/listeners.ts"(e,r,s){"use strict";s.r(r),s.d(r,{LISTENERS:()=>o,addStateListener:()=>g,removeStateListener:()=>m,runStateChangeListeners:()=>i});var t=s("./src/index.ts"),n=s("./src/constants.ts"),a=s("./src/helpers.ts");const o={};async function i(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:o}=t.STATE[r];for(const r of e){const e=r.bind(null,[o],s,n);(0,a.isAsyncFunction)(r)?await e():e()}}const i=`${r()}${n.NAMESPACE_DELIMITER}`.length,g=(0,a.map)(e,e=>e.slice(i));for(const t of o[r()]){const r=t.bind(null,g,s,(0,a.map)(e,(e,r)=>[e.slice(i),r]));(0,a.isAsyncFunction)(t)?await r():r()}}}function g(e,r,s){return(0,a.isFunction)(r)||(0,a.isAsyncFunction)(r)?(o[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)||(0,a.isAsyncFunction)(r)){const s=o[e()].findIndex(e=>e===r);return o[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},REMOVE_KEY:function(e,r){e&&localStorage.removeItem(r)}}},"./src/webextension-storage.ts"(e,r,s){"use strict";s.r(r),s.d(r,{default:()=>n,isBackgroundScript:()=>o,isSessionStorageSupport:()=>a});const t=s("./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"),n={GET_TYPE:function(e){return o()&&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},REMOVE_KEY:async function(e,r){e&&await t.storage[e].remove(r)}};function a(){return!!t.storage.session}function o(){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",o=(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,o)=>{if(r.fallbackToNoCallback)try{s[e](...t,n({resolve:a,reject:o},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:o},r))})},i=(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 c=e[a];if("function"==typeof c)if("function"==typeof r[a])c=i(e,e[a],r[a]);else if(g(s,a)){let r=o(a,s[a]);c=i(e,e[a],r)}else c=c.bind(e);else if("object"==typeof c&&null!==c&&(g(r,a)||g(s,a)))c=m(c,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}}),c;c=m(c,r[a],s["*"])}return t[a]=c,c},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)})},c=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))}}),l=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,o,i=!1,g=new Promise(e=>{a=function(r){i=!0,e(r)}});try{o=e(r,s,a)}catch(e){o=Promise.reject(e)}const m=!0!==o&&t(o);if(!0!==o&&!m&&!i)return!1;const c=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 c(m?o: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)})},f={devtools:{network:{onRequestFinished:c(l)}},runtime:{onMessage:c(A),onMessageExternal:c(A),sendMessage:d.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:d.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},x={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return r.privacy={network:{"*":x},services:{"*":x},websites:{"*":x}},m(e,f,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:()=>i});var e=s("./src/index.ts"),r=s("./src/webextension-storage.ts");const n=s("./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"),{joinStateChanges:a,setStorageUtils:o}=e.default;(0,r.isBackgroundScript)()&&(n.storage.local.onChanged.addListener(a),(0,r.isSessionStorageSupport)()&&n.storage.session.onChanged.addListener(a)),o(r.default);const i=e.default})(),t=t.default,t})());
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){for(const[s,n]of Object.entries(r))t.STATE[e(s)]={key:s,namespace:e,value:n.bind(null,(0,t.createStore)(e())),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:()=>d,forEach:()=>u,getParamNames:()=>l,isArray:()=>a,isAsyncFunction:()=>g,isFunction:()=>i,isObject:()=>m,isString:()=>o,map:()=>A,recreateStructure:()=>f,uid:()=>x});const t=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,n=/([^\s,]+)/g;function a(e){return"[object Array]"===c(e)}function o(e){return"[object String]"===c(e)}function i(e){return"[object Function]"===c(e)}function g(e){return"[object AsyncFunction]"===c(e)}function m(e){return"[object Object]"===c(e)}function c(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 A(e,r){const s=Object.entries(e).map(([e,s])=>r(e,s));return 2===s[0]?.length?Object.fromEntries(s):s}function u(e,r){Object.entries(e||{}).forEach(([e,s])=>r(e,s))}function d(e,r){return Object.fromEntries(Object.entries(e||{}).filter(([e,s])=>!0===r(e,s)))}function f(e){let r=e;if(a(e))return r=[],e.forEach(e=>r.push(f(e))),r;if(m(e)){r={};for(let s in e)r[s]=f(e[s]);return r}return r}function x(){return Date.now().toString(36)+Math.random().toString(36).substr(2)}},"./src/index.ts"(e,r,s){"use strict";s.r(r),s.d(r,{STATE:()=>g,createPendingChanges:()=>v,createStore:()=>O,default:()=>C,getState:()=>h,getValues:()=>f,joinStateChanges:()=>p,resetState:()=>w,setState:()=>S,setupValue:()=>u});var t=s("./src/storage.ts"),n=s("./src/helpers.ts"),a=s("./src/actions.ts"),o=s("./src/constants.ts"),i=s("./src/listeners.ts");const g={},m={},c={},l={};async function A(e,r,s){const t=l.GET_TYPE(s),a=Object.assign({},r),o=(0,n.map)(r,(r,s)=>[e(r),s]);l.IS_AVAILABE(t)&&await l.UPDATE_STATE(o,t);for(const s in r){const r=e(s);g[r]=u(s,e,o[r],a[s],t)}return O(e())}function u(e,r,s,t,a){const o=r(e),i=(0,n.isFunction)(s),m=i?(0,n.getParamNames)(s):[];return m.forEach(e=>{const s=r(e);g[s]||(g[s]={dependants:[],dependencies:[],namespace:r,storageType:a}),g[s].dependants?.push(o)}),{key:e,fullKey:o,value:i?s.apply(null,x(m,r)):s,computeFn:i&&s,dependencies:m,dependants:[],listeners:[],defaultValue:t,storageType:a,namespace:r}}function d(e){return(0,n.filter)(g,(r,{key:s})=>r===e(s))}function f(e){return(0,n.map)(d(e),(e,{key:r,value:s})=>[r,s])}function x(e,r){const s=f(r);return e.map(e=>s[e])}async function p(e){for(const[r,{storageTypes:s,readyStorageTypes:t,changes:n}]of Object.entries(m))if(e[r]){const a=e[r].newValue;t[a]=!0,delete e[r],Object.assign(n,e),l.IS_AVAILABE(a)&&l.REMOVE_KEY(a,r);for(const e in s)if(!t[e])return;delete m[r],await b(n)}}async function b(e){const r={};for(const s in e){const t=g[s].value,n=e[s].newValue;t!==n?(r[s]={newValue:n,prevValue:t},g[s].value=n):r[s]={isSame:!0},y(s,e,r)}await(0,i.runStateChangeListeners)((0,n.filter)(r,(e,r)=>!r.isSame))}function y(e,r,s){g[e].dependants?.forEach(e=>{const{dependencies:t,namespace:n}=g[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=g[e].value,o=g[e].computeFn?.apply(null,x(t,n));a!==o&&(s[e]={newValue:o,prevValue:a},g[e].value=o,y(e,r,s))})}function h(e,r){return(0,n.isString)(r)?O(r):(0,n.recreateStructure)(f(e))}async function S(e,r){const s={},t=(0,n.uid)(),a={};(0,n.forEach)(r,(r,t)=>{const n=e(r),{storageType:o,computeFn:i,isAction:m}=g[n];i||m||(s[o]||(s[o]={}),a[o]=!0,s[o][n]=t)}),m[t]={storageTypes:a,readyStorageTypes:{},changes:{}};for(let[e,r]of Object.entries(s))await E(e,{...r,[t]:e});return O(e())}async function E(e,r){if(l.IS_AVAILABE(e)){if(await l.SET_VALUES(e,r))return}p((0,n.map)(r,(e,r)=>[e,{newValue:r}]))}async function w(e,r){return await S(e,T(e,r)),O(e())}function T(e,r){const s=d(e);return(0,n.map)(r?(0,n.filter)(s,(e,{key:s})=>r.includes(s)):s,(e,{key:r,defaultValue:s})=>[r,s])}function v(e){const r=()=>{const r=c[e()];return c[e()]={},r};return{add:r=>Object.assign(c[e()],r),reset:r=>Object.assign(c[e()],T(e,r)),get:()=>c[e()],flush:r,commit:()=>S(e,r())}}function k(e){return!arguments[1]||(0,n.isString)(arguments[1])?h.apply(null,arguments):(0,n.isArray)(arguments[1])||(0,n.isFunction)(arguments[1])||(0,n.isAsyncFunction)(arguments[1])?i.addStateListener.apply(null,arguments):(0,n.isObject)(arguments[1])?S.apply(null,arguments):void 0}function j(e){Object.assign(l,e)}function O(e){const r=r=>function(e,r){return`${e}${(0,n.isString)(r)&&o.NAMESPACE_DELIMITER||""}${r||""}`}(e,r);return c[r()]||(c[r()]={}),i.LISTENERS[r()]||(i.LISTENERS[r()]=[]),Object.assign(k.bind(null,r),{add:e=>A(r,e,!1),addPersistent:e=>A(r,e,!0),get:e=>h(r,e),set:async e=>await S(r,e),reset:e=>w(r,e),changes:v(r),onChange:(e,s)=>(0,i.addStateListener)(r,e,s),removeListener:(e,s)=>(0,i.removeStateListener)(r,e,s),actions:e=>(0,a.addStateActions)(r,e),setStorageUtils:j,joinStateChanges:p,namespace:r})}j(t.default);const C=O("")},"./src/listeners.ts"(e,r,s){"use strict";s.r(r),s.d(r,{LISTENERS:()=>o,addStateListener:()=>g,removeStateListener:()=>m,runStateChangeListeners:()=>i});var t=s("./src/index.ts"),n=s("./src/constants.ts"),a=s("./src/helpers.ts");const o={};async function i(e){if(Object.keys(e).length){const{namespace:r}=t.STATE[Object.keys(e)[0]];for(const[s]of Object.entries(e)){const{listeners:e,key:n}=t.STATE[s];for(const s of e){const e=s.bind(null,[n],(0,t.createStore)(r()));(0,a.isAsyncFunction)(s)?await e():e()}}const s=`${r()}${n.NAMESPACE_DELIMITER}`.length,i=(0,a.map)(e,e=>e.slice(s));for(const e of o[r()]){const s=e.bind(null,i,(0,t.createStore)(r()));(0,a.isAsyncFunction)(e)?await s():s()}}}function g(e,r,s){return(0,a.isFunction)(r)||(0,a.isAsyncFunction)(r)?(o[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)||(0,a.isAsyncFunction)(r)){const s=o[e()].findIndex(e=>e===r);return o[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},REMOVE_KEY:function(e,r){e&&localStorage.removeItem(r)}}},"./src/webextension-storage.ts"(e,r,s){"use strict";s.r(r),s.d(r,{default:()=>n,isBackgroundScript:()=>o,isSessionStorageSupport:()=>a});const t=s("./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"),n={GET_TYPE:function(e){return o()&&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},REMOVE_KEY:async function(e,r){e&&await t.storage[e].remove(r)}};function a(){return!!t.storage.session}function o(){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",o=(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,o)=>{if(r.fallbackToNoCallback)try{s[e](...t,n({resolve:a,reject:o},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:o},r))})},i=(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 c=e[a];if("function"==typeof c)if("function"==typeof r[a])c=i(e,e[a],r[a]);else if(g(s,a)){let r=o(a,s[a]);c=i(e,e[a],r)}else c=c.bind(e);else if("object"==typeof c&&null!==c&&(g(r,a)||g(s,a)))c=m(c,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}}),c;c=m(c,r[a],s["*"])}return t[a]=c,c},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)})},c=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))}}),l=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,o,i=!1,g=new Promise(e=>{a=function(r){i=!0,e(r)}});try{o=e(r,s,a)}catch(e){o=Promise.reject(e)}const m=!0!==o&&t(o);if(!0!==o&&!m&&!i)return!1;const c=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 c(m?o: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)})},f={devtools:{network:{onRequestFinished:c(l)}},runtime:{onMessage:c(A),onMessageExternal:c(A),sendMessage:d.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:d.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},x={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return r.privacy={network:{"*":x},services:{"*":x},websites:{"*":x}},m(e,f,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:()=>i});var e=s("./src/index.ts"),r=s("./src/webextension-storage.ts");const n=s("./node_modules/webextension-polyfill/dist/browser-polyfill.min.js"),{joinStateChanges:a,setStorageUtils:o}=e.default;(0,r.isBackgroundScript)()&&(n.storage.local.onChanged.addListener(a),(0,r.isSessionStorageSupport)()&&n.storage.session.onChanged.addListener(a)),o(r.default);const i=e.default})(),t=t.default,t})());
package/dist/varstor.js CHANGED
@@ -25,16 +25,11 @@ __webpack_require__.r(__webpack_exports__);
25
25
  /* harmony import */ var ___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! . */ "./src/index.ts");
26
26
 
27
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)) {
28
+ for (const [actionName, actionFn] of Object.entries(actions)) {
34
29
  ___WEBPACK_IMPORTED_MODULE_0__.STATE[namespace(actionName)] = {
35
30
  key: actionName,
36
31
  namespace,
37
- value: actionFn.bind(null, stateAcessor),
32
+ value: actionFn.bind(null, (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace())),
38
33
  isAction: true,
39
34
  listeners: [],
40
35
  };
@@ -154,6 +149,7 @@ function uid() {
154
149
  __webpack_require__.r(__webpack_exports__);
155
150
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
156
151
  /* harmony export */ STATE: () => (/* binding */ STATE),
152
+ /* harmony export */ createPendingChanges: () => (/* binding */ createPendingChanges),
157
153
  /* harmony export */ createStore: () => (/* binding */ createStore),
158
154
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
159
155
  /* harmony export */ getState: () => (/* binding */ getState),
@@ -174,7 +170,8 @@ __webpack_require__.r(__webpack_exports__);
174
170
 
175
171
 
176
172
  const STATE = {};
177
- const WAITING_CHANGES = {};
173
+ const STATE_CHANGED_PIECES = {};
174
+ const STATE_PENDING_CHANGES = {};
178
175
  const STORAGE = {};
179
176
  setStorageUtils(_storage__WEBPACK_IMPORTED_MODULE_0__["default"]);
180
177
  async function addState(namespace, initialState, isPersistent) {
@@ -184,9 +181,6 @@ async function addState(namespace, initialState, isPersistent) {
184
181
  if (STORAGE.IS_AVAILABE(storageType)) {
185
182
  await STORAGE.UPDATE_STATE(values, storageType);
186
183
  }
187
- if (!_listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()]) {
188
- _listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()] = [];
189
- }
190
184
  for (const key in initialState) {
191
185
  const fullKey = namespace(key);
192
186
  STATE[fullKey] = setupValue(key, namespace, values[fullKey], defaultValues[key], storageType);
@@ -240,7 +234,7 @@ function getArguments(dependencies, namespace) {
240
234
  return dependencies.map((name) => values[name]);
241
235
  }
242
236
  async function joinStateChanges(changesPiece) {
243
- for (const [updateId, { storageTypes, readyStorageTypes, changes },] of Object.entries(WAITING_CHANGES)) {
237
+ for (const [updateId, { storageTypes, readyStorageTypes, changes },] of Object.entries(STATE_CHANGED_PIECES)) {
244
238
  if (changesPiece[updateId]) {
245
239
  const storageType = changesPiece[updateId].newValue;
246
240
  readyStorageTypes[storageType] = true;
@@ -254,7 +248,7 @@ async function joinStateChanges(changesPiece) {
254
248
  return;
255
249
  }
256
250
  }
257
- delete WAITING_CHANGES[updateId];
251
+ delete STATE_CHANGED_PIECES[updateId];
258
252
  await onStateChange(changes);
259
253
  }
260
254
  }
@@ -320,7 +314,7 @@ async function setState(namespace, changes) {
320
314
  storageTypes[storageType] = true;
321
315
  storageChanges[storageType][fullKey] = v;
322
316
  });
323
- WAITING_CHANGES[updateId] = {
317
+ STATE_CHANGED_PIECES[updateId] = {
324
318
  storageTypes,
325
319
  readyStorageTypes: {},
326
320
  changes: {},
@@ -340,17 +334,34 @@ async function setValues(storageType, changes) {
340
334
  joinStateChanges((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(changes, (k, newValue) => [k, { newValue }]));
341
335
  }
342
336
  async function resetState(namespace, keys) {
337
+ await setState(namespace, getDefaultValues(namespace, keys));
338
+ return createStore(namespace());
339
+ }
340
+ function getDefaultValues(namespace, keys) {
343
341
  const namespaceState = getNamespaceState(namespace);
344
- await setState(namespace, (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(keys
342
+ return (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(keys
345
343
  ? (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(namespaceState, (k, { key }) => keys.includes(key))
346
- : namespaceState, (k, { key, defaultValue }) => [key, defaultValue]));
347
- return createStore(namespace());
344
+ : namespaceState, (k, { key, defaultValue }) => [key, defaultValue]);
345
+ }
346
+ function createPendingChanges(namespace) {
347
+ const flush = () => {
348
+ const changes = STATE_PENDING_CHANGES[namespace()];
349
+ STATE_PENDING_CHANGES[namespace()] = {};
350
+ return changes;
351
+ };
352
+ return {
353
+ add: (changes) => Object.assign(STATE_PENDING_CHANGES[namespace()], changes),
354
+ reset: (keys) => Object.assign(STATE_PENDING_CHANGES[namespace()], getDefaultValues(namespace, keys)),
355
+ get: () => STATE_PENDING_CHANGES[namespace()],
356
+ flush,
357
+ commit: () => setState(namespace, flush()),
358
+ };
348
359
  }
349
360
  function main(namespace) {
350
361
  if (!arguments[1] || (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isString)(arguments[1])) {
351
362
  return getState.apply(null, arguments);
352
363
  }
353
- if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isArray)(arguments[1])) {
364
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isArray)(arguments[1]) || (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isFunction)(arguments[1]) || (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isAsyncFunction)(arguments[1])) {
354
365
  return _listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener.apply(null, arguments);
355
366
  }
356
367
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isObject)(arguments[1])) {
@@ -365,12 +376,19 @@ function addNamespace(namespace, str) {
365
376
  }
366
377
  function createStore(_namespace) {
367
378
  const namespace = ((key) => addNamespace(_namespace, key));
379
+ if (!STATE_PENDING_CHANGES[namespace()]) {
380
+ STATE_PENDING_CHANGES[namespace()] = {};
381
+ }
382
+ if (!_listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()]) {
383
+ _listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()] = [];
384
+ }
368
385
  return Object.assign(main.bind(null, namespace), {
369
386
  add: (state) => addState(namespace, state, false),
370
387
  addPersistent: (state) => addState(namespace, state, true),
371
388
  get: (newNamespace) => getState(namespace, newNamespace),
372
389
  set: async (changes) => await setState(namespace, changes),
373
390
  reset: (keys) => resetState(namespace, keys),
391
+ changes: createPendingChanges(namespace),
374
392
  onChange: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener)(namespace, keys, cb),
375
393
  removeListener: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.removeStateListener)(namespace, keys, cb),
376
394
  actions: (actions) => (0,_actions__WEBPACK_IMPORTED_MODULE_2__.addStateActions)(namespace, actions),
@@ -407,11 +425,10 @@ const LISTENERS = {};
407
425
  async function runStateChangeListeners(realChanges) {
408
426
  if (Object.keys(realChanges).length) {
409
427
  const { namespace } = ___WEBPACK_IMPORTED_MODULE_0__.STATE[Object.keys(realChanges)[0]];
410
- const stateValues = (0,___WEBPACK_IMPORTED_MODULE_0__.getValues)(namespace);
411
- for (let [changeKey, change] of Object.entries(realChanges)) {
428
+ for (const [changeKey] of Object.entries(realChanges)) {
412
429
  const { listeners, key } = ___WEBPACK_IMPORTED_MODULE_0__.STATE[changeKey];
413
430
  for (const cb of listeners) {
414
- const fn = cb.bind(null, [key], stateValues, change);
431
+ const fn = cb.bind(null, [key], (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace()));
415
432
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(cb)) {
416
433
  await fn();
417
434
  }
@@ -423,10 +440,7 @@ async function runStateChangeListeners(realChanges) {
423
440
  const namespaceLength = `${namespace()}${_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER}`.length;
424
441
  const readableKeys = (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k) => k.slice(namespaceLength));
425
442
  for (const cb of LISTENERS[namespace()]) {
426
- const fn = cb.bind(null, readableKeys, stateValues, (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k, v) => [
427
- k.slice(namespaceLength),
428
- v,
429
- ]));
443
+ const fn = cb.bind(null, readableKeys, (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace()));
430
444
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(cb)) {
431
445
  await fn();
432
446
  }
@@ -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/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,o]of Object.entries(t))r.STATE[e(s)]={key:s,namespace:e,value:o.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:()=>S,forEach:()=>p,getParamNames:()=>f,isArray:()=>o,isAsyncFunction:()=>a,isFunction:()=>i,isObject:()=>u,isString:()=>c,map:()=>d,recreateStructure:()=>y,uid:()=>E});const r=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,s=/([^\s,]+)/g;function o(e){return"[object Array]"===l(e)}function c(e){return"[object String]"===l(e)}function i(e){return"[object Function]"===l(e)}function a(e){return"[object AsyncFunction]"===l(e)}function u(e){return"[object Object]"===l(e)}function l(e){return Object.prototype.toString.call(e)}function f(e){const t=e.toString().replace(r,"").split("=>")[0],n=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(s);return null===n?[]:n}function d(e,t){const n=Object.entries(e).map(([e,n])=>t(e,n));return 2===n[0]?.length?Object.fromEntries(n):n}function p(e,t){Object.entries(e||{}).forEach(([e,n])=>t(e,n))}function S(e,t){return Object.fromEntries(Object.entries(e||{}).filter(([e,n])=>!0===t(e,n)))}function y(e){let t=e;if(o(e))return t=[],e.forEach(e=>t.push(y(e))),t;if(u(e)){t={};for(let n in e)t[n]=y(e[n]);return t}return t}function E(){return Date.now().toString(36)+Math.random().toString(36).substr(2)}},"./src/index.ts"(e,t,n){n.r(t),n.d(t,{STATE:()=>a,createStore:()=>v,default:()=>I,getState:()=>m,getValues:()=>S,joinStateChanges:()=>E,resetState:()=>j,setState:()=>A,setupValue:()=>d});var r=n("./src/storage.ts"),s=n("./src/helpers.ts"),o=n("./src/actions.ts"),c=n("./src/constants.ts"),i=n("./src/listeners.ts");const a={},u={},l={};async function f(e,t,n){const r=l.GET_TYPE(n),o=Object.assign({},t),c=(0,s.map)(t,(t,n)=>[e(t),n]);l.IS_AVAILABE(r)&&await l.UPDATE_STATE(c,r),i.LISTENERS[e()]||(i.LISTENERS[e()]=[]);for(const n in t){const t=e(n);a[t]=d(n,e,c[t],o[n],r)}return v(e())}function d(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,y(u,t)):n,computeFn:i&&n,dependencies:u,dependants:[],listeners:[],defaultValue:r,storageType:o,namespace:t}}function p(e){return(0,s.filter)(a,(t,{key:n})=>t===e(n))}function S(e){return(0,s.map)(p(e),(e,{key:t,value:n})=>[t,n])}function y(e,t){const n=S(t);return e.map(e=>n[e])}async function E(e){for(const[t,{storageTypes:n,readyStorageTypes:r,changes:s}]of Object.entries(u))if(e[t]){const o=e[t].newValue;r[o]=!0,delete e[t],Object.assign(s,e),l.IS_AVAILABE(o)&&l.REMOVE_KEY(o,t);for(const e in n)if(!r[e])return;delete u[t],await g(s)}}async function g(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},b(n,e,t)}await(0,i.runStateChangeListeners)((0,s.filter)(t,(e,t)=>!t.isSame))}function b(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,y(r,s));o!==c&&(n[e]={newValue:c,prevValue:o},a[e].value=c,b(e,t,n))})}function m(e,t){return(0,s.isString)(t)?v(t):(0,s.recreateStructure)(S(e))}async function A(e,t){const n={},r=(0,s.uid)(),o={};(0,s.forEach)(t,(t,r)=>{const s=e(t),{storageType:c,computeFn:i,isAction:u}=a[s];i||u||(n[c]||(n[c]={}),o[c]=!0,n[c][s]=r)}),u[r]={storageTypes:o,readyStorageTypes:{},changes:{}};for(let[e,t]of Object.entries(n))await T(e,{...t,[r]:e});return v(e())}async function T(e,t){if(l.IS_AVAILABE(e)){if(await l.SET_VALUES(e,t))return}E((0,s.map)(t,(e,t)=>[e,{newValue:t}]))}async function j(e,t){const n=p(e);return await A(e,(0,s.map)(t?(0,s.filter)(n,(e,{key:n})=>t.includes(n)):n,(e,{key:t,defaultValue:n})=>[t,n])),v(e())}function O(e){return!arguments[1]||(0,s.isString)(arguments[1])?m.apply(null,arguments):(0,s.isArray)(arguments[1])?i.addStateListener.apply(null,arguments):(0,s.isObject)(arguments[1])?A.apply(null,arguments):void 0}function h(e){Object.assign(l,e)}function v(e){const t=t=>function(e,t){return`${e}${(0,s.isString)(t)&&c.NAMESPACE_DELIMITER||""}${t||""}`}(e,t);return Object.assign(O.bind(null,t),{add:e=>f(t,e,!1),addPersistent:e=>f(t,e,!0),get:e=>m(t,e),set:async e=>await A(t,e),reset:e=>j(t,e),onChange:(e,n)=>(0,i.addStateListener)(t,e,n),removeListener:(e,n)=>(0,i.removeStateListener)(t,e,n),actions:e=>(0,o.addStateActions)(t,e),setStorageUtils:h,joinStateChanges:E,namespace:t})}h(r.default);const I=v("")},"./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:c}=r.STATE[t];for(const t of e){const e=t.bind(null,[c],n,s);(0,o.isAsyncFunction)(t)?await e():e()}}const i=`${t()}${s.NAMESPACE_DELIMITER}`.length,a=(0,o.map)(e,e=>e.slice(i));for(const r of c[t()]){const t=r.bind(null,a,n,(0,o.map)(e,(e,t)=>[e.slice(i),t]));(0,o.isAsyncFunction)(r)?await t():t()}}}function a(e,t,n){return(0,o.isFunction)(t)||(0,o.isAsyncFunction)(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)||(0,o.isAsyncFunction)(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},REMOVE_KEY:function(e,t){e&&localStorage.removeItem(t)}}}};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){for(const[n,s]of Object.entries(t))r.STATE[e(n)]={key:n,namespace:e,value:s.bind(null,(0,r.createStore)(e())),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:()=>S,forEach:()=>p,getParamNames:()=>f,isArray:()=>c,isAsyncFunction:()=>a,isFunction:()=>i,isObject:()=>u,isString:()=>o,map:()=>d,recreateStructure:()=>y,uid:()=>g});const r=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,s=/([^\s,]+)/g;function c(e){return"[object Array]"===l(e)}function o(e){return"[object String]"===l(e)}function i(e){return"[object Function]"===l(e)}function a(e){return"[object AsyncFunction]"===l(e)}function u(e){return"[object Object]"===l(e)}function l(e){return Object.prototype.toString.call(e)}function f(e){const t=e.toString().replace(r,"").split("=>")[0],n=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(s);return null===n?[]:n}function d(e,t){const n=Object.entries(e).map(([e,n])=>t(e,n));return 2===n[0]?.length?Object.fromEntries(n):n}function p(e,t){Object.entries(e||{}).forEach(([e,n])=>t(e,n))}function S(e,t){return Object.fromEntries(Object.entries(e||{}).filter(([e,n])=>!0===t(e,n)))}function y(e){let t=e;if(c(e))return t=[],e.forEach(e=>t.push(y(e))),t;if(u(e)){t={};for(let n in e)t[n]=y(e[n]);return t}return t}function g(){return Date.now().toString(36)+Math.random().toString(36).substr(2)}},"./src/index.ts"(e,t,n){n.r(t),n.d(t,{STATE:()=>a,createPendingChanges:()=>v,createStore:()=>V,default:()=>_,getState:()=>A,getValues:()=>y,joinStateChanges:()=>E,resetState:()=>O,setState:()=>j,setupValue:()=>p});var r=n("./src/storage.ts"),s=n("./src/helpers.ts"),c=n("./src/actions.ts"),o=n("./src/constants.ts"),i=n("./src/listeners.ts");const a={},u={},l={},f={};async function d(e,t,n){const r=f.GET_TYPE(n),c=Object.assign({},t),o=(0,s.map)(t,(t,n)=>[e(t),n]);f.IS_AVAILABE(r)&&await f.UPDATE_STATE(o,r);for(const n in t){const t=e(n);a[t]=p(n,e,o[t],c[n],r)}return V(e())}function p(e,t,n,r,c){const o=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:c}),a[n].dependants?.push(o)}),{key:e,fullKey:o,value:i?n.apply(null,g(u,t)):n,computeFn:i&&n,dependencies:u,dependants:[],listeners:[],defaultValue:r,storageType:c,namespace:t}}function S(e){return(0,s.filter)(a,(t,{key:n})=>t===e(n))}function y(e){return(0,s.map)(S(e),(e,{key:t,value:n})=>[t,n])}function g(e,t){const n=y(t);return e.map(e=>n[e])}async function E(e){for(const[t,{storageTypes:n,readyStorageTypes:r,changes:s}]of Object.entries(u))if(e[t]){const c=e[t].newValue;r[c]=!0,delete e[t],Object.assign(s,e),f.IS_AVAILABE(c)&&f.REMOVE_KEY(c,t);for(const e in n)if(!r[e])return;delete u[t],await b(s)}}async function b(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},m(n,e,t)}await(0,i.runStateChangeListeners)((0,s.filter)(t,(e,t)=>!t.isSame))}function m(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 c=a[e].value,o=a[e].computeFn?.apply(null,g(r,s));c!==o&&(n[e]={newValue:o,prevValue:c},a[e].value=o,m(e,t,n))})}function A(e,t){return(0,s.isString)(t)?V(t):(0,s.recreateStructure)(y(e))}async function j(e,t){const n={},r=(0,s.uid)(),c={};(0,s.forEach)(t,(t,r)=>{const s=e(t),{storageType:o,computeFn:i,isAction:u}=a[s];i||u||(n[o]||(n[o]={}),c[o]=!0,n[o][s]=r)}),u[r]={storageTypes:c,readyStorageTypes:{},changes:{}};for(let[e,t]of Object.entries(n))await T(e,{...t,[r]:e});return V(e())}async function T(e,t){if(f.IS_AVAILABE(e)){if(await f.SET_VALUES(e,t))return}E((0,s.map)(t,(e,t)=>[e,{newValue:t}]))}async function O(e,t){return await j(e,h(e,t)),V(e())}function h(e,t){const n=S(e);return(0,s.map)(t?(0,s.filter)(n,(e,{key:n})=>t.includes(n)):n,(e,{key:t,defaultValue:n})=>[t,n])}function v(e){const t=()=>{const t=l[e()];return l[e()]={},t};return{add:t=>Object.assign(l[e()],t),reset:t=>Object.assign(l[e()],h(e,t)),get:()=>l[e()],flush:t,commit:()=>j(e,t())}}function I(e){return!arguments[1]||(0,s.isString)(arguments[1])?A.apply(null,arguments):(0,s.isArray)(arguments[1])||(0,s.isFunction)(arguments[1])||(0,s.isAsyncFunction)(arguments[1])?i.addStateListener.apply(null,arguments):(0,s.isObject)(arguments[1])?j.apply(null,arguments):void 0}function L(e){Object.assign(f,e)}function V(e){const t=t=>function(e,t){return`${e}${(0,s.isString)(t)&&o.NAMESPACE_DELIMITER||""}${t||""}`}(e,t);return l[t()]||(l[t()]={}),i.LISTENERS[t()]||(i.LISTENERS[t()]=[]),Object.assign(I.bind(null,t),{add:e=>d(t,e,!1),addPersistent:e=>d(t,e,!0),get:e=>A(t,e),set:async e=>await j(t,e),reset:e=>O(t,e),changes:v(t),onChange:(e,n)=>(0,i.addStateListener)(t,e,n),removeListener:(e,n)=>(0,i.removeStateListener)(t,e,n),actions:e=>(0,c.addStateActions)(t,e),setStorageUtils:L,joinStateChanges:E,namespace:t})}L(r.default);const _=V("")},"./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]];for(const[n]of Object.entries(e)){const{listeners:e,key:s}=r.STATE[n];for(const n of e){const e=n.bind(null,[s],(0,r.createStore)(t()));(0,c.isAsyncFunction)(n)?await e():e()}}const n=`${t()}${s.NAMESPACE_DELIMITER}`.length,i=(0,c.map)(e,e=>e.slice(n));for(const e of o[t()]){const n=e.bind(null,i,(0,r.createStore)(t()));(0,c.isAsyncFunction)(e)?await n():n()}}}function a(e,t,n){return(0,c.isFunction)(t)||(0,c.isAsyncFunction)(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)||(0,c.isAsyncFunction)(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},REMOVE_KEY:function(e,t){e&&localStorage.removeItem(t)}}}};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.64",
3
+ "version": "0.6.65",
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 CHANGED
@@ -1,17 +1,11 @@
1
- import { STATE, getState, setState, resetState } from ".";
1
+ import { STATE, createStore } from ".";
2
2
 
3
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)) {
4
+ for (const [actionName, actionFn] of Object.entries(actions)) {
11
5
  STATE[namespace(actionName)] = {
12
6
  key: actionName,
13
7
  namespace,
14
- value: actionFn.bind(null, stateAcessor),
8
+ value: actionFn.bind(null, createStore(namespace())),
15
9
  isAction: true,
16
10
  listeners: [],
17
11
  };
package/src/index.ts CHANGED
@@ -11,6 +11,7 @@ import {
11
11
  recreateStructure,
12
12
  forEach,
13
13
  uid,
14
+ isAsyncFunction,
14
15
  } from "./helpers";
15
16
 
16
17
  import { addStateActions } from "./actions";
@@ -25,7 +26,8 @@ import {
25
26
  } from "./listeners";
26
27
 
27
28
  export const STATE = {} as IState;
28
- const WAITING_CHANGES = {} as IStateUpdatePieces;
29
+ const STATE_CHANGED_PIECES = {} as IStateUpdatePieces;
30
+ const STATE_PENDING_CHANGES = {} as IStatePendingChanges;
29
31
  const STORAGE = {} as IStorageFunctions;
30
32
 
31
33
  setStorageUtils(storageUtils);
@@ -46,10 +48,6 @@ async function addState(
46
48
  await STORAGE.UPDATE_STATE(values, storageType as string);
47
49
  }
48
50
 
49
- if (!LISTENERS[namespace()]) {
50
- LISTENERS[namespace()] = [];
51
- }
52
-
53
51
  for (const key in initialState) {
54
52
  const fullKey = namespace(key);
55
53
  STATE[fullKey] = setupValue(
@@ -129,7 +127,7 @@ export async function joinStateChanges(changesPiece: IStateChanges) {
129
127
  for (const [
130
128
  updateId,
131
129
  { storageTypes, readyStorageTypes, changes },
132
- ] of Object.entries(WAITING_CHANGES)) {
130
+ ] of Object.entries(STATE_CHANGED_PIECES)) {
133
131
  if (changesPiece[updateId]) {
134
132
  const storageType = changesPiece[updateId].newValue;
135
133
  readyStorageTypes[storageType] = true;
@@ -145,7 +143,7 @@ export async function joinStateChanges(changesPiece: IStateChanges) {
145
143
  }
146
144
  }
147
145
 
148
- delete WAITING_CHANGES[updateId];
146
+ delete STATE_CHANGED_PIECES[updateId];
149
147
 
150
148
  await onStateChange(changes);
151
149
  }
@@ -254,7 +252,7 @@ export async function setState(
254
252
  storageChanges[storageType!][fullKey] = v;
255
253
  });
256
254
 
257
- WAITING_CHANGES[updateId] = {
255
+ STATE_CHANGED_PIECES[updateId] = {
258
256
  storageTypes,
259
257
  readyStorageTypes: {},
260
258
  changes: {},
@@ -284,19 +282,41 @@ async function setValues(
284
282
  }
285
283
 
286
284
  export async function resetState(namespace: INamespace, keys?: string[]) {
285
+ await setState(namespace, getDefaultValues(namespace, keys));
286
+
287
+ return createStore(namespace());
288
+ }
289
+
290
+ function getDefaultValues(namespace: INamespace, keys?: string[]) {
287
291
  const namespaceState = getNamespaceState(namespace);
288
292
 
289
- await setState(
290
- namespace,
291
- map(
292
- keys
293
- ? filter(namespaceState, (k, { key }) => keys.includes(key!))
294
- : namespaceState,
295
- (k, { key, defaultValue }) => [key, defaultValue],
296
- ) as Record<string, any>,
297
- );
293
+ return map(
294
+ keys
295
+ ? filter(namespaceState, (k, { key }) => keys.includes(key!))
296
+ : namespaceState,
297
+ (k, { key, defaultValue }) => [key, defaultValue],
298
+ ) as Record<string, any>;
299
+ }
298
300
 
299
- return createStore(namespace());
301
+ export function createPendingChanges(namespace: INamespace) {
302
+ const flush = () => {
303
+ const changes = STATE_PENDING_CHANGES[namespace()];
304
+ STATE_PENDING_CHANGES[namespace()] = {};
305
+ return changes;
306
+ }
307
+
308
+ return {
309
+ add: (changes: Record<string, any>) =>
310
+ Object.assign(STATE_PENDING_CHANGES[namespace()], changes),
311
+ reset: (keys: string[]) =>
312
+ Object.assign(
313
+ STATE_PENDING_CHANGES[namespace()],
314
+ getDefaultValues(namespace, keys),
315
+ ),
316
+ get: () => STATE_PENDING_CHANGES[namespace()],
317
+ flush,
318
+ commit: () => setState(namespace, flush()),
319
+ };
300
320
  }
301
321
 
302
322
  function main(namespace: INamespace): any {
@@ -304,7 +324,7 @@ function main(namespace: INamespace): any {
304
324
  return getState.apply(null, arguments as unknown as [INamespace, string]);
305
325
  }
306
326
 
307
- if (isArray(arguments[1])) {
327
+ if (isArray(arguments[1]) || isFunction(arguments[1]) || isAsyncFunction(arguments[1])) {
308
328
  return addStateListener.apply(
309
329
  null,
310
330
  arguments as unknown as [INamespace, string[], () => {}],
@@ -331,6 +351,14 @@ export function createStore(_namespace: string) {
331
351
  const namespace = ((key: string) =>
332
352
  addNamespace(_namespace, key)) as INamespace;
333
353
 
354
+ if (!STATE_PENDING_CHANGES[namespace()]) {
355
+ STATE_PENDING_CHANGES[namespace()] = {};
356
+ }
357
+
358
+ if (!LISTENERS[namespace()]) {
359
+ LISTENERS[namespace()] = [];
360
+ }
361
+
334
362
  return Object.assign(main.bind(null, namespace), {
335
363
  add: (state: IStateDefault) => addState(namespace, state, false),
336
364
  addPersistent: (state: IStateDefault) => addState(namespace, state, true),
@@ -338,6 +366,7 @@ export function createStore(_namespace: string) {
338
366
  set: async (changes: Record<string, unknown>) =>
339
367
  await setState(namespace, changes),
340
368
  reset: (keys: string[]) => resetState(namespace, keys),
369
+ changes: createPendingChanges(namespace),
341
370
  onChange: (keys: string[], cb: () => {}) =>
342
371
  addStateListener(namespace, keys, cb),
343
372
  removeListener: (keys: string[], cb: () => {}) =>
package/src/listeners.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { STATE, getValues, createStore } from ".";
1
+ import { STATE, createStore } from ".";
2
2
  import { NAMESPACE_DELIMITER } from "./constants";
3
3
  import { map, isFunction, isAsyncFunction } from "./helpers";
4
4
 
@@ -8,12 +8,10 @@ export async function runStateChangeListeners(realChanges: IStateChanges) {
8
8
  if (Object.keys(realChanges).length) {
9
9
  const { namespace } =
10
10
  STATE[Object.keys(realChanges)[0] as keyof typeof STATE];
11
- const stateValues = getValues(namespace);
12
-
13
- for (let [changeKey, change] of Object.entries(realChanges)) {
11
+ for (const [changeKey] of Object.entries(realChanges)) {
14
12
  const { listeners, key } = STATE[changeKey];
15
13
  for (const cb of listeners!) {
16
- const fn = cb.bind(null, [key], stateValues, change);
14
+ const fn = cb.bind(null, [key], createStore(namespace()));
17
15
  if (isAsyncFunction(cb)) {
18
16
  await fn();
19
17
  } else {
@@ -31,11 +29,7 @@ export async function runStateChangeListeners(realChanges: IStateChanges) {
31
29
  const fn = cb.bind(
32
30
  null,
33
31
  readableKeys,
34
- stateValues,
35
- map(realChanges, (k, v) => [
36
- k.slice(namespaceLength),
37
- v,
38
- ]) as IStateChanges,
32
+ createStore(namespace())
39
33
  );
40
34
  if (isAsyncFunction(cb)) {
41
35
  await fn();
package/src/types.d.ts CHANGED
@@ -34,8 +34,7 @@ type IStorageFunctions = {
34
34
 
35
35
  type IStateListener = (
36
36
  changes: string[],
37
- values: Record<string, any>,
38
- data: IStateChanges,
37
+ store: Record<string, any>,
39
38
  ) => any;
40
39
 
41
40
  type IStateListeners = Record<string, IStateListener[]>;
@@ -48,4 +47,6 @@ type IStateUpdatePieces = Record<string, {
48
47
  storageTypes: Record<string, boolean>;
49
48
  readyStorageTypes: Record<string, boolean>;
50
49
  changes: IStateChanges;
51
- }>;
50
+ }>;
51
+
52
+ type IStatePendingChanges = Record<string, Record<string, any>>;