varstor 0.6.63 → 0.6.64

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
@@ -45,7 +45,7 @@ The library object features the following methods:
45
45
  ```
46
46
 
47
47
  ## Creation ```.add()```/```.addPersistent()``` <a name="creation"></a>
48
- Values are added to the store with add or addPersistent methods. They perform the same functionality, except addPersistent saves state to the storage and lets you reuse it between browser sessions.
48
+ Values are added to the store with ```add``` or ```addPersistent``` methods. They perform the same functionality, except ```addPersistent``` saves state to the storage and lets you reuse it between browser sessions.
49
49
 
50
50
  ```js
51
51
  async Varstor.add(
@@ -61,7 +61,10 @@ Where:
61
61
  ```KeysValues {}``` - a standard object with keys and values, where ```key``` is a name of piece of state, and ```value``` is a default value or ```ReactiveFunction```
62
62
  ```ReactiveFunction``` - re-evalutes and updates its value automatically each time arguments in ```valueNames``` list change. ```valueNames``` are any state values defined before the ```ReactiveFunction```. ```computedValue```s are not saved in storage.
63
63
 
64
- **Important: ```add``` and ```addPersistent``` are asynchronous operations; you must `await` or use ```Promise.then``` to ensure all the data is ready to work with!**
64
+ > [!WARNING]
65
+ > ```add``` and ```addPersistent``` are asynchronous operations; you must `await` or use ```Promise.then``` to ensure all the data is ready to work with!
66
+
67
+
65
68
 
66
69
  ## Dynamic reevaluation (```ReactiveFunction```) <a name="reactivefunction"></a>
67
70
  Values can change automatically with the help of ```ReactiveFunction```s when one or more of the other values in the namespace change.
@@ -99,7 +102,6 @@ async Varstor.set(
99
102
  }
100
103
  ) => Varstor
101
104
  ```
102
- **Important: values are updated asynchronously; don't assume the script will recognize the change immediately on the next line. Instead, ```await``` or make use of ```onChange``` listeners!**
103
105
 
104
106
  To reset values back to defaults:
105
107
  ```js
@@ -108,6 +110,9 @@ async Varstor.reset(Keys []) => Varstor
108
110
  Where:
109
111
  ```Keys[]``` (optional) - array of keys to return to default values. If omitted all values will be returned to defaults.
110
112
 
113
+ > [!WARNING]
114
+ > 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!
115
+
111
116
 
112
117
  ## Listening ```.onChange()```/```.removeListener()``` <a name="listening"></a>
113
118
 
@@ -134,17 +139,17 @@ the same parameter usage.
134
139
 
135
140
 
136
141
  ## 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.
142
+ Hide away all public data access and mutation into dedicated functions with the help of ```StateAction```s.
138
143
  ```js
139
144
  Varstor.actions({
140
145
  KeysActions {
141
- key1: IStateAction1 (Varstor, ...arguments[]) => void
142
- key2: IStateAction2 (Varstor, ...arguments[]) => void
146
+ key1: StateAction1 (Varstor, ...arguments[]) => void
147
+ key2: StateAction2 (Varstor, ...arguments[]) => void
143
148
  ...
144
149
  }
145
150
  })
146
151
  ```
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.
152
+ ```StateAction``` 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
153
  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
154
  ```js
150
155
  Varstor.add({ x: 1 });
@@ -73,11 +73,13 @@ __webpack_require__.r(__webpack_exports__);
73
73
  /* harmony export */ forEach: () => (/* binding */ forEach),
74
74
  /* harmony export */ getParamNames: () => (/* binding */ getParamNames),
75
75
  /* harmony export */ isArray: () => (/* binding */ isArray),
76
+ /* harmony export */ isAsyncFunction: () => (/* binding */ isAsyncFunction),
76
77
  /* harmony export */ isFunction: () => (/* binding */ isFunction),
77
78
  /* harmony export */ isObject: () => (/* binding */ isObject),
78
79
  /* harmony export */ isString: () => (/* binding */ isString),
79
80
  /* harmony export */ map: () => (/* binding */ map),
80
- /* harmony export */ recreateStructure: () => (/* binding */ recreateStructure)
81
+ /* harmony export */ recreateStructure: () => (/* binding */ recreateStructure),
82
+ /* harmony export */ uid: () => (/* binding */ uid)
81
83
  /* harmony export */ });
82
84
  const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
83
85
  const ARGUMENT_NAMES = /([^\s,]+)/g;
@@ -90,6 +92,9 @@ function isString(obj) {
90
92
  function isFunction(obj) {
91
93
  return getObjectType(obj) === "[object Function]";
92
94
  }
95
+ function isAsyncFunction(obj) {
96
+ return getObjectType(obj) === "[object AsyncFunction]";
97
+ }
93
98
  function isObject(obj) {
94
99
  return getObjectType(obj) === "[object Object]";
95
100
  }
@@ -135,6 +140,9 @@ function recreateStructure(value) {
135
140
  }
136
141
  return newValue;
137
142
  }
143
+ function uid() {
144
+ return Date.now().toString(36) + Math.random().toString(36).substr(2);
145
+ }
138
146
 
139
147
 
140
148
  /***/ },
@@ -153,6 +161,7 @@ __webpack_require__.r(__webpack_exports__);
153
161
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
154
162
  /* harmony export */ getState: () => (/* binding */ getState),
155
163
  /* harmony export */ getValues: () => (/* binding */ getValues),
164
+ /* harmony export */ joinStateChanges: () => (/* binding */ joinStateChanges),
156
165
  /* harmony export */ resetState: () => (/* binding */ resetState),
157
166
  /* harmony export */ setState: () => (/* binding */ setState),
158
167
  /* harmony export */ setupValue: () => (/* binding */ setupValue)
@@ -161,15 +170,14 @@ __webpack_require__.r(__webpack_exports__);
161
170
  /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ "./src/helpers.ts");
162
171
  /* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./actions */ "./src/actions.ts");
163
172
  /* 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
-
173
+ /* harmony import */ var _listeners__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./listeners */ "./src/listeners.ts");
167
174
 
168
175
 
169
176
 
170
177
 
171
178
 
172
179
  const STATE = {};
180
+ const WAITING_CHANGES = {};
173
181
  const STORAGE = {};
174
182
  setStorageUtils(_storage__WEBPACK_IMPORTED_MODULE_0__["default"]);
175
183
  async function addState(namespace, initialState, isPersistent) {
@@ -179,12 +187,11 @@ async function addState(namespace, initialState, isPersistent) {
179
187
  if (STORAGE.IS_AVAILABE(storageType)) {
180
188
  await STORAGE.UPDATE_STATE(values, storageType);
181
189
  }
182
- if (!_listeners__WEBPACK_IMPORTED_MODULE_5__.LISTENERS[namespace()]) {
183
- _listeners__WEBPACK_IMPORTED_MODULE_5__.LISTENERS[namespace()] = [];
190
+ if (!_listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()]) {
191
+ _listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()] = [];
184
192
  }
185
193
  for (const key in initialState) {
186
194
  const fullKey = namespace(key);
187
- _validation__WEBPACK_IMPORTED_MODULE_4__.isValid.Defining(fullKey);
188
195
  STATE[fullKey] = setupValue(key, namespace, values[fullKey], defaultValues[key], storageType);
189
196
  }
190
197
  return createStore(namespace());
@@ -235,6 +242,26 @@ function getArguments(dependencies, namespace) {
235
242
  const values = getValues(namespace);
236
243
  return dependencies.map((name) => values[name]);
237
244
  }
245
+ async function joinStateChanges(changesPiece) {
246
+ for (const [updateId, { storageTypes, readyStorageTypes, changes },] of Object.entries(WAITING_CHANGES)) {
247
+ if (changesPiece[updateId]) {
248
+ const storageType = changesPiece[updateId].newValue;
249
+ readyStorageTypes[storageType] = true;
250
+ delete changesPiece[updateId];
251
+ Object.assign(changes, changesPiece);
252
+ if (STORAGE.IS_AVAILABE(storageType)) {
253
+ STORAGE.REMOVE_KEY(storageType, updateId);
254
+ }
255
+ for (const key in storageTypes) {
256
+ if (!readyStorageTypes[key]) {
257
+ return;
258
+ }
259
+ }
260
+ delete WAITING_CHANGES[updateId];
261
+ await onStateChange(changes);
262
+ }
263
+ }
264
+ }
238
265
  async function onStateChange(changes) {
239
266
  const realChanges = {};
240
267
  for (const key in changes) {
@@ -249,7 +276,7 @@ async function onStateChange(changes) {
249
276
  }
250
277
  updateDependencies(key, changes, realChanges);
251
278
  }
252
- await (0,_listeners__WEBPACK_IMPORTED_MODULE_5__.runStateChangeListeners)((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(realChanges, (k, v) => !v.isSame));
279
+ await (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.runStateChangeListeners)((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(realChanges, (k, v) => !v.isSame));
253
280
  }
254
281
  function updateDependencies(key, changes, realChanges) {
255
282
  STATE[key].dependants?.forEach((name) => {
@@ -282,6 +309,8 @@ function getState(namespace, arg) {
282
309
  }
283
310
  async function setState(namespace, changes) {
284
311
  const storageChanges = {};
312
+ const updateId = (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.uid)();
313
+ const storageTypes = {};
285
314
  (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.forEach)(changes, (k, v) => {
286
315
  const fullKey = namespace(k);
287
316
  const { storageType, computeFn, isAction } = STATE[fullKey];
@@ -291,10 +320,16 @@ async function setState(namespace, changes) {
291
320
  if (!storageChanges[storageType]) {
292
321
  storageChanges[storageType] = {};
293
322
  }
323
+ storageTypes[storageType] = true;
294
324
  storageChanges[storageType][fullKey] = v;
295
325
  });
326
+ WAITING_CHANGES[updateId] = {
327
+ storageTypes,
328
+ readyStorageTypes: {},
329
+ changes: {},
330
+ };
296
331
  for (let [storageType, changes] of Object.entries(storageChanges)) {
297
- await setValues(storageType, changes);
332
+ await setValues(storageType, { ...changes, [updateId]: storageType });
298
333
  }
299
334
  return createStore(namespace());
300
335
  }
@@ -305,7 +340,7 @@ async function setValues(storageType, changes) {
305
340
  return;
306
341
  }
307
342
  }
308
- onStateChange((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(changes, (k, newValue) => [k, { newValue }]));
343
+ joinStateChanges((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(changes, (k, newValue) => [k, { newValue }]));
309
344
  }
310
345
  async function resetState(namespace, keys) {
311
346
  const namespaceState = getNamespaceState(namespace);
@@ -319,7 +354,7 @@ function main(namespace) {
319
354
  return getState.apply(null, arguments);
320
355
  }
321
356
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isArray)(arguments[1])) {
322
- return _listeners__WEBPACK_IMPORTED_MODULE_5__.addStateListener.apply(null, arguments);
357
+ return _listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener.apply(null, arguments);
323
358
  }
324
359
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isObject)(arguments[1])) {
325
360
  return setState.apply(null, arguments);
@@ -339,11 +374,12 @@ function createStore(_namespace) {
339
374
  get: (newNamespace) => getState(namespace, newNamespace),
340
375
  set: async (changes) => await setState(namespace, changes),
341
376
  reset: (keys) => resetState(namespace, keys),
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),
377
+ onChange: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener)(namespace, keys, cb),
378
+ removeListener: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.removeStateListener)(namespace, keys, cb),
344
379
  actions: (actions) => (0,_actions__WEBPACK_IMPORTED_MODULE_2__.addStateActions)(namespace, actions),
345
380
  setStorageUtils,
346
- onStateChange,
381
+ joinStateChanges,
382
+ namespace,
347
383
  });
348
384
  }
349
385
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createStore(""));
@@ -379,20 +415,33 @@ async function runStateChangeListeners(realChanges) {
379
415
  for (let [changeKey, change] of Object.entries(realChanges)) {
380
416
  const { listeners, key } = ___WEBPACK_IMPORTED_MODULE_0__.STATE[changeKey];
381
417
  for (const cb of listeners) {
382
- await cb([key], stateValues, change);
418
+ const fn = cb.bind(null, [key], stateValues, change);
419
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(cb)) {
420
+ await fn();
421
+ }
422
+ else {
423
+ fn();
424
+ }
383
425
  }
384
426
  }
385
- const readableKeys = (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k) => k.slice(_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER.length));
427
+ const namespaceLength = `${namespace()}${_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER}`.length;
428
+ const readableKeys = (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k) => k.slice(namespaceLength));
386
429
  for (const cb of LISTENERS[namespace()]) {
387
- await cb(readableKeys, stateValues, (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k, v) => [
388
- k.slice(_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER.length),
430
+ const fn = cb.bind(null, readableKeys, stateValues, (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k, v) => [
431
+ k.slice(namespaceLength),
389
432
  v,
390
433
  ]));
434
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(cb)) {
435
+ await fn();
436
+ }
437
+ else {
438
+ fn();
439
+ }
391
440
  }
392
441
  }
393
442
  }
394
443
  function addStateListener(namespace, observables, cb) {
395
- if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observables)) {
444
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observables) || (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(observables)) {
396
445
  LISTENERS[namespace()].push(observables);
397
446
  return (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace());
398
447
  }
@@ -400,7 +449,7 @@ function addStateListener(namespace, observables, cb) {
400
449
  return (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace());
401
450
  }
402
451
  function removeStateListener(namespace, observables, removeCb) {
403
- if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observables)) {
452
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observables) || (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(observables)) {
404
453
  const removeIdx = LISTENERS[namespace()].findIndex((cb) => cb === observables);
405
454
  LISTENERS[namespace()].splice(removeIdx, 1);
406
455
  return (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace());
@@ -449,53 +498,20 @@ async function setStorageValue(storageType, changes) {
449
498
  }
450
499
  return false;
451
500
  }
501
+ function removeStorageKey(type, key) {
502
+ if (type) {
503
+ localStorage.removeItem(key);
504
+ }
505
+ }
452
506
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
453
507
  GET_TYPE: getStorageType,
454
508
  IS_AVAILABE: isStorageAvailable,
455
509
  UPDATE_STATE: updateFromLocalStorage,
456
510
  SET_VALUES: setStorageValue,
511
+ REMOVE_KEY: removeStorageKey,
457
512
  });
458
513
 
459
514
 
460
- /***/ },
461
-
462
- /***/ "./src/validation.ts"
463
- /*!***************************!*\
464
- !*** ./src/validation.ts ***!
465
- \***************************/
466
- (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
467
-
468
- "use strict";
469
- __webpack_require__.r(__webpack_exports__);
470
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
471
- /* harmony export */ isValid: () => (/* binding */ isValid)
472
- /* harmony export */ });
473
- /* harmony import */ var ___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! . */ "./src/index.ts");
474
- /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./constants */ "./src/constants.ts");
475
-
476
-
477
- function splitFullKey(fullKey) {
478
- const segments = fullKey.split(_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER);
479
- return [segments.slice(-1)[0], segments.join(_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER)];
480
- }
481
- const isValid = {
482
- Setting: (fullKey) => {
483
- if (!___WEBPACK_IMPORTED_MODULE_0__.STATE[fullKey]) {
484
- const [key, namespace] = splitFullKey(fullKey);
485
- throw new Error(`Setting "${key}" key in "${namespace}" namespace. DOES NOT EXIST`);
486
- }
487
- return true;
488
- },
489
- Defining: (fullKey) => {
490
- if (___WEBPACK_IMPORTED_MODULE_0__.STATE[fullKey]) {
491
- const [key, namespace] = splitFullKey(fullKey);
492
- throw new Error(`Redefining "${key}" key in "${namespace}" namespace. ALREADY DEFINED`);
493
- }
494
- return true;
495
- },
496
- };
497
-
498
-
499
515
  /***/ },
500
516
 
501
517
  /***/ "./src/webextension-storage.ts"
@@ -517,6 +533,7 @@ const browser = __webpack_require__(/*! webextension-polyfill/dist/browser-polyf
517
533
  IS_AVAILABE: isStorageAvailable,
518
534
  UPDATE_STATE: updateStateFromStorage,
519
535
  SET_VALUES: setStorageValue,
536
+ REMOVE_KEY: removeStorageKey,
520
537
  });
521
538
  function getStorageType(isPersistent) {
522
539
  return (isBackgroundScript() && isPersistent && "local") || "session";
@@ -532,6 +549,11 @@ async function setStorageValue(type, changes) {
532
549
  await browser.storage[type].set(changes);
533
550
  return true;
534
551
  }
552
+ async function removeStorageKey(type, key) {
553
+ if (type) {
554
+ await browser.storage[type].remove(key);
555
+ }
556
+ }
535
557
  function isSessionStorageSupport() {
536
558
  return !!browser.storage.session;
537
559
  }
@@ -658,11 +680,11 @@ __webpack_require__.r(__webpack_exports__);
658
680
  const browser = __webpack_require__(/*! webextension-polyfill/dist/browser-polyfill.min */ "./node_modules/webextension-polyfill/dist/browser-polyfill.min.js");
659
681
 
660
682
 
661
- const { onStateChange, setStorageUtils } = ___WEBPACK_IMPORTED_MODULE_0__["default"];
683
+ const { joinStateChanges, setStorageUtils } = ___WEBPACK_IMPORTED_MODULE_0__["default"];
662
684
  if ((0,_webextension_storage__WEBPACK_IMPORTED_MODULE_1__.isBackgroundScript)()) {
663
- browser.storage.local.onChanged.addListener(onStateChange);
685
+ browser.storage.local.onChanged.addListener(joinStateChanges);
664
686
  (0,_webextension_storage__WEBPACK_IMPORTED_MODULE_1__.isSessionStorageSupport)() &&
665
- browser.storage.session.onChanged.addListener(onStateChange);
687
+ browser.storage.session.onChanged.addListener(joinStateChanges);
666
688
  }
667
689
  setStorageUtils(_webextension_storage__WEBPACK_IMPORTED_MODULE_1__["default"]);
668
690
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___WEBPACK_IMPORTED_MODULE_0__["default"]);
@@ -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:()=>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})());
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})());
package/dist/varstor.js CHANGED
@@ -71,11 +71,13 @@ __webpack_require__.r(__webpack_exports__);
71
71
  /* harmony export */ forEach: () => (/* binding */ forEach),
72
72
  /* harmony export */ getParamNames: () => (/* binding */ getParamNames),
73
73
  /* harmony export */ isArray: () => (/* binding */ isArray),
74
+ /* harmony export */ isAsyncFunction: () => (/* binding */ isAsyncFunction),
74
75
  /* harmony export */ isFunction: () => (/* binding */ isFunction),
75
76
  /* harmony export */ isObject: () => (/* binding */ isObject),
76
77
  /* harmony export */ isString: () => (/* binding */ isString),
77
78
  /* harmony export */ map: () => (/* binding */ map),
78
- /* harmony export */ recreateStructure: () => (/* binding */ recreateStructure)
79
+ /* harmony export */ recreateStructure: () => (/* binding */ recreateStructure),
80
+ /* harmony export */ uid: () => (/* binding */ uid)
79
81
  /* harmony export */ });
80
82
  const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
81
83
  const ARGUMENT_NAMES = /([^\s,]+)/g;
@@ -88,6 +90,9 @@ function isString(obj) {
88
90
  function isFunction(obj) {
89
91
  return getObjectType(obj) === "[object Function]";
90
92
  }
93
+ function isAsyncFunction(obj) {
94
+ return getObjectType(obj) === "[object AsyncFunction]";
95
+ }
91
96
  function isObject(obj) {
92
97
  return getObjectType(obj) === "[object Object]";
93
98
  }
@@ -133,6 +138,9 @@ function recreateStructure(value) {
133
138
  }
134
139
  return newValue;
135
140
  }
141
+ function uid() {
142
+ return Date.now().toString(36) + Math.random().toString(36).substr(2);
143
+ }
136
144
 
137
145
 
138
146
  /***/ },
@@ -150,6 +158,7 @@ __webpack_require__.r(__webpack_exports__);
150
158
  /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
151
159
  /* harmony export */ getState: () => (/* binding */ getState),
152
160
  /* harmony export */ getValues: () => (/* binding */ getValues),
161
+ /* harmony export */ joinStateChanges: () => (/* binding */ joinStateChanges),
153
162
  /* harmony export */ resetState: () => (/* binding */ resetState),
154
163
  /* harmony export */ setState: () => (/* binding */ setState),
155
164
  /* harmony export */ setupValue: () => (/* binding */ setupValue)
@@ -158,15 +167,14 @@ __webpack_require__.r(__webpack_exports__);
158
167
  /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ "./src/helpers.ts");
159
168
  /* harmony import */ var _actions__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./actions */ "./src/actions.ts");
160
169
  /* 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
-
170
+ /* harmony import */ var _listeners__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./listeners */ "./src/listeners.ts");
164
171
 
165
172
 
166
173
 
167
174
 
168
175
 
169
176
  const STATE = {};
177
+ const WAITING_CHANGES = {};
170
178
  const STORAGE = {};
171
179
  setStorageUtils(_storage__WEBPACK_IMPORTED_MODULE_0__["default"]);
172
180
  async function addState(namespace, initialState, isPersistent) {
@@ -176,12 +184,11 @@ async function addState(namespace, initialState, isPersistent) {
176
184
  if (STORAGE.IS_AVAILABE(storageType)) {
177
185
  await STORAGE.UPDATE_STATE(values, storageType);
178
186
  }
179
- if (!_listeners__WEBPACK_IMPORTED_MODULE_5__.LISTENERS[namespace()]) {
180
- _listeners__WEBPACK_IMPORTED_MODULE_5__.LISTENERS[namespace()] = [];
187
+ if (!_listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()]) {
188
+ _listeners__WEBPACK_IMPORTED_MODULE_4__.LISTENERS[namespace()] = [];
181
189
  }
182
190
  for (const key in initialState) {
183
191
  const fullKey = namespace(key);
184
- _validation__WEBPACK_IMPORTED_MODULE_4__.isValid.Defining(fullKey);
185
192
  STATE[fullKey] = setupValue(key, namespace, values[fullKey], defaultValues[key], storageType);
186
193
  }
187
194
  return createStore(namespace());
@@ -232,6 +239,26 @@ function getArguments(dependencies, namespace) {
232
239
  const values = getValues(namespace);
233
240
  return dependencies.map((name) => values[name]);
234
241
  }
242
+ async function joinStateChanges(changesPiece) {
243
+ for (const [updateId, { storageTypes, readyStorageTypes, changes },] of Object.entries(WAITING_CHANGES)) {
244
+ if (changesPiece[updateId]) {
245
+ const storageType = changesPiece[updateId].newValue;
246
+ readyStorageTypes[storageType] = true;
247
+ delete changesPiece[updateId];
248
+ Object.assign(changes, changesPiece);
249
+ if (STORAGE.IS_AVAILABE(storageType)) {
250
+ STORAGE.REMOVE_KEY(storageType, updateId);
251
+ }
252
+ for (const key in storageTypes) {
253
+ if (!readyStorageTypes[key]) {
254
+ return;
255
+ }
256
+ }
257
+ delete WAITING_CHANGES[updateId];
258
+ await onStateChange(changes);
259
+ }
260
+ }
261
+ }
235
262
  async function onStateChange(changes) {
236
263
  const realChanges = {};
237
264
  for (const key in changes) {
@@ -246,7 +273,7 @@ async function onStateChange(changes) {
246
273
  }
247
274
  updateDependencies(key, changes, realChanges);
248
275
  }
249
- await (0,_listeners__WEBPACK_IMPORTED_MODULE_5__.runStateChangeListeners)((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(realChanges, (k, v) => !v.isSame));
276
+ await (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.runStateChangeListeners)((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.filter)(realChanges, (k, v) => !v.isSame));
250
277
  }
251
278
  function updateDependencies(key, changes, realChanges) {
252
279
  STATE[key].dependants?.forEach((name) => {
@@ -279,6 +306,8 @@ function getState(namespace, arg) {
279
306
  }
280
307
  async function setState(namespace, changes) {
281
308
  const storageChanges = {};
309
+ const updateId = (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.uid)();
310
+ const storageTypes = {};
282
311
  (0,_helpers__WEBPACK_IMPORTED_MODULE_1__.forEach)(changes, (k, v) => {
283
312
  const fullKey = namespace(k);
284
313
  const { storageType, computeFn, isAction } = STATE[fullKey];
@@ -288,10 +317,16 @@ async function setState(namespace, changes) {
288
317
  if (!storageChanges[storageType]) {
289
318
  storageChanges[storageType] = {};
290
319
  }
320
+ storageTypes[storageType] = true;
291
321
  storageChanges[storageType][fullKey] = v;
292
322
  });
323
+ WAITING_CHANGES[updateId] = {
324
+ storageTypes,
325
+ readyStorageTypes: {},
326
+ changes: {},
327
+ };
293
328
  for (let [storageType, changes] of Object.entries(storageChanges)) {
294
- await setValues(storageType, changes);
329
+ await setValues(storageType, { ...changes, [updateId]: storageType });
295
330
  }
296
331
  return createStore(namespace());
297
332
  }
@@ -302,7 +337,7 @@ async function setValues(storageType, changes) {
302
337
  return;
303
338
  }
304
339
  }
305
- onStateChange((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(changes, (k, newValue) => [k, { newValue }]));
340
+ joinStateChanges((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.map)(changes, (k, newValue) => [k, { newValue }]));
306
341
  }
307
342
  async function resetState(namespace, keys) {
308
343
  const namespaceState = getNamespaceState(namespace);
@@ -316,7 +351,7 @@ function main(namespace) {
316
351
  return getState.apply(null, arguments);
317
352
  }
318
353
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isArray)(arguments[1])) {
319
- return _listeners__WEBPACK_IMPORTED_MODULE_5__.addStateListener.apply(null, arguments);
354
+ return _listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener.apply(null, arguments);
320
355
  }
321
356
  if ((0,_helpers__WEBPACK_IMPORTED_MODULE_1__.isObject)(arguments[1])) {
322
357
  return setState.apply(null, arguments);
@@ -336,11 +371,12 @@ function createStore(_namespace) {
336
371
  get: (newNamespace) => getState(namespace, newNamespace),
337
372
  set: async (changes) => await setState(namespace, changes),
338
373
  reset: (keys) => resetState(namespace, keys),
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),
374
+ onChange: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.addStateListener)(namespace, keys, cb),
375
+ removeListener: (keys, cb) => (0,_listeners__WEBPACK_IMPORTED_MODULE_4__.removeStateListener)(namespace, keys, cb),
341
376
  actions: (actions) => (0,_actions__WEBPACK_IMPORTED_MODULE_2__.addStateActions)(namespace, actions),
342
377
  setStorageUtils,
343
- onStateChange,
378
+ joinStateChanges,
379
+ namespace,
344
380
  });
345
381
  }
346
382
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createStore(""));
@@ -375,20 +411,33 @@ async function runStateChangeListeners(realChanges) {
375
411
  for (let [changeKey, change] of Object.entries(realChanges)) {
376
412
  const { listeners, key } = ___WEBPACK_IMPORTED_MODULE_0__.STATE[changeKey];
377
413
  for (const cb of listeners) {
378
- await cb([key], stateValues, change);
414
+ const fn = cb.bind(null, [key], stateValues, change);
415
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(cb)) {
416
+ await fn();
417
+ }
418
+ else {
419
+ fn();
420
+ }
379
421
  }
380
422
  }
381
- const readableKeys = (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k) => k.slice(_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER.length));
423
+ const namespaceLength = `${namespace()}${_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER}`.length;
424
+ const readableKeys = (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k) => k.slice(namespaceLength));
382
425
  for (const cb of LISTENERS[namespace()]) {
383
- await cb(readableKeys, stateValues, (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k, v) => [
384
- k.slice(_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER.length),
426
+ const fn = cb.bind(null, readableKeys, stateValues, (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.map)(realChanges, (k, v) => [
427
+ k.slice(namespaceLength),
385
428
  v,
386
429
  ]));
430
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(cb)) {
431
+ await fn();
432
+ }
433
+ else {
434
+ fn();
435
+ }
387
436
  }
388
437
  }
389
438
  }
390
439
  function addStateListener(namespace, observables, cb) {
391
- if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observables)) {
440
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observables) || (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(observables)) {
392
441
  LISTENERS[namespace()].push(observables);
393
442
  return (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace());
394
443
  }
@@ -396,7 +445,7 @@ function addStateListener(namespace, observables, cb) {
396
445
  return (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace());
397
446
  }
398
447
  function removeStateListener(namespace, observables, removeCb) {
399
- if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observables)) {
448
+ if ((0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observables) || (0,_helpers__WEBPACK_IMPORTED_MODULE_2__.isAsyncFunction)(observables)) {
400
449
  const removeIdx = LISTENERS[namespace()].findIndex((cb) => cb === observables);
401
450
  LISTENERS[namespace()].splice(removeIdx, 1);
402
451
  return (0,___WEBPACK_IMPORTED_MODULE_0__.createStore)(namespace());
@@ -444,52 +493,20 @@ async function setStorageValue(storageType, changes) {
444
493
  }
445
494
  return false;
446
495
  }
496
+ function removeStorageKey(type, key) {
497
+ if (type) {
498
+ localStorage.removeItem(key);
499
+ }
500
+ }
447
501
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
448
502
  GET_TYPE: getStorageType,
449
503
  IS_AVAILABE: isStorageAvailable,
450
504
  UPDATE_STATE: updateFromLocalStorage,
451
505
  SET_VALUES: setStorageValue,
506
+ REMOVE_KEY: removeStorageKey,
452
507
  });
453
508
 
454
509
 
455
- /***/ },
456
-
457
- /***/ "./src/validation.ts"
458
- /*!***************************!*\
459
- !*** ./src/validation.ts ***!
460
- \***************************/
461
- (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
462
-
463
- __webpack_require__.r(__webpack_exports__);
464
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
465
- /* harmony export */ isValid: () => (/* binding */ isValid)
466
- /* harmony export */ });
467
- /* harmony import */ var ___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! . */ "./src/index.ts");
468
- /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./constants */ "./src/constants.ts");
469
-
470
-
471
- function splitFullKey(fullKey) {
472
- const segments = fullKey.split(_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER);
473
- return [segments.slice(-1)[0], segments.join(_constants__WEBPACK_IMPORTED_MODULE_1__.NAMESPACE_DELIMITER)];
474
- }
475
- const isValid = {
476
- Setting: (fullKey) => {
477
- if (!___WEBPACK_IMPORTED_MODULE_0__.STATE[fullKey]) {
478
- const [key, namespace] = splitFullKey(fullKey);
479
- throw new Error(`Setting "${key}" key in "${namespace}" namespace. DOES NOT EXIST`);
480
- }
481
- return true;
482
- },
483
- Defining: (fullKey) => {
484
- if (___WEBPACK_IMPORTED_MODULE_0__.STATE[fullKey]) {
485
- const [key, namespace] = splitFullKey(fullKey);
486
- throw new Error(`Redefining "${key}" key in "${namespace}" namespace. ALREADY DEFINED`);
487
- }
488
- return true;
489
- },
490
- };
491
-
492
-
493
510
  /***/ }
494
511
 
495
512
  /******/ });
@@ -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,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})());
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})());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "varstor",
3
- "version": "0.6.63",
3
+ "version": "0.6.64",
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/helpers.ts CHANGED
@@ -13,6 +13,10 @@ export function isFunction(obj: unknown) {
13
13
  return getObjectType(obj) === "[object Function]";
14
14
  }
15
15
 
16
+ export function isAsyncFunction (obj: unknown) {
17
+ return getObjectType(obj) === "[object AsyncFunction]";
18
+ }
19
+
16
20
  export function isObject(obj: unknown) {
17
21
  return getObjectType(obj) === "[object Object]";
18
22
  }
@@ -86,3 +90,7 @@ export function recreateStructure(value: unknown) {
86
90
 
87
91
  return newValue;
88
92
  }
93
+
94
+ export function uid() {
95
+ return Date.now().toString(36) + Math.random().toString(36).substr(2);
96
+ }
package/src/index.ts CHANGED
@@ -10,13 +10,13 @@ import {
10
10
  filter,
11
11
  recreateStructure,
12
12
  forEach,
13
+ uid,
13
14
  } from "./helpers";
14
15
 
15
16
  import { addStateActions } from "./actions";
16
17
 
17
18
  import { NAMESPACE_DELIMITER } from "./constants";
18
19
 
19
- import { isValid } from "./validation";
20
20
  import {
21
21
  runStateChangeListeners,
22
22
  addStateListener,
@@ -25,6 +25,7 @@ import {
25
25
  } from "./listeners";
26
26
 
27
27
  export const STATE = {} as IState;
28
+ const WAITING_CHANGES = {} as IStateUpdatePieces;
28
29
  const STORAGE = {} as IStorageFunctions;
29
30
 
30
31
  setStorageUtils(storageUtils);
@@ -51,7 +52,6 @@ async function addState(
51
52
 
52
53
  for (const key in initialState) {
53
54
  const fullKey = namespace(key);
54
- isValid.Defining(fullKey);
55
55
  STATE[fullKey] = setupValue(
56
56
  key,
57
57
  namespace,
@@ -125,6 +125,33 @@ function getArguments(dependencies: string[], namespace: INamespace) {
125
125
  return dependencies.map((name) => values[name as keyof typeof values]);
126
126
  }
127
127
 
128
+ export async function joinStateChanges(changesPiece: IStateChanges) {
129
+ for (const [
130
+ updateId,
131
+ { storageTypes, readyStorageTypes, changes },
132
+ ] of Object.entries(WAITING_CHANGES)) {
133
+ if (changesPiece[updateId]) {
134
+ const storageType = changesPiece[updateId].newValue;
135
+ readyStorageTypes[storageType] = true;
136
+ delete changesPiece[updateId];
137
+ Object.assign(changes, changesPiece);
138
+ if (STORAGE.IS_AVAILABE(storageType)) {
139
+ STORAGE.REMOVE_KEY(storageType, updateId);
140
+ }
141
+
142
+ for (const key in storageTypes) {
143
+ if (!readyStorageTypes[key]) {
144
+ return;
145
+ }
146
+ }
147
+
148
+ delete WAITING_CHANGES[updateId];
149
+
150
+ await onStateChange(changes);
151
+ }
152
+ }
153
+ }
154
+
128
155
  async function onStateChange(changes: IStateChanges) {
129
156
  const realChanges = {} as IStateChanges;
130
157
 
@@ -207,6 +234,8 @@ export async function setState(
207
234
  changes: Record<string, unknown>,
208
235
  ): Promise<unknown> {
209
236
  const storageChanges: Record<string, any> = {};
237
+ const updateId = uid();
238
+ const storageTypes = {} as Record<string, boolean>;
210
239
 
211
240
  forEach(changes, (k, v) => {
212
241
  const fullKey = namespace(k);
@@ -220,11 +249,19 @@ export async function setState(
220
249
  storageChanges[storageType!] = {};
221
250
  }
222
251
 
252
+ storageTypes[storageType!] = true;
253
+
223
254
  storageChanges[storageType!][fullKey] = v;
224
255
  });
225
256
 
257
+ WAITING_CHANGES[updateId] = {
258
+ storageTypes,
259
+ readyStorageTypes: {},
260
+ changes: {},
261
+ };
262
+
226
263
  for (let [storageType, changes] of Object.entries(storageChanges)) {
227
- await setValues(storageType, changes);
264
+ await setValues(storageType, { ...changes, [updateId]: storageType });
228
265
  }
229
266
 
230
267
  return createStore(namespace());
@@ -241,7 +278,7 @@ async function setValues(
241
278
  }
242
279
  }
243
280
 
244
- onStateChange(
281
+ joinStateChanges(
245
282
  map(changes, (k, newValue) => [k, { newValue }]) as Record<string, any>,
246
283
  );
247
284
  }
@@ -307,7 +344,8 @@ export function createStore(_namespace: string) {
307
344
  removeStateListener(namespace, keys, cb),
308
345
  actions: (actions: IStateActions) => addStateActions(namespace, actions),
309
346
  setStorageUtils,
310
- onStateChange,
347
+ joinStateChanges,
348
+ namespace,
311
349
  });
312
350
  }
313
351
 
package/src/listeners.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { STATE, getValues, createStore } from ".";
2
2
  import { NAMESPACE_DELIMITER } from "./constants";
3
- import { map, isFunction } from "./helpers";
3
+ import { map, isFunction, isAsyncFunction } from "./helpers";
4
4
 
5
5
  export const LISTENERS = {} as IStateListeners;
6
6
 
@@ -13,23 +13,35 @@ export async function runStateChangeListeners(realChanges: IStateChanges) {
13
13
  for (let [changeKey, change] of Object.entries(realChanges)) {
14
14
  const { listeners, key } = STATE[changeKey];
15
15
  for (const cb of listeners!) {
16
- await cb([key], stateValues, change);
16
+ const fn = cb.bind(null, [key], stateValues, change);
17
+ if (isAsyncFunction(cb)) {
18
+ await fn();
19
+ } else {
20
+ fn();
21
+ }
17
22
  }
18
23
  }
19
24
 
25
+ const namespaceLength = `${namespace()}${NAMESPACE_DELIMITER}`.length;
20
26
  const readableKeys = map(realChanges, (k) =>
21
- k.slice(NAMESPACE_DELIMITER.length),
27
+ k.slice(namespaceLength),
22
28
  ) as string[];
23
29
 
24
30
  for (const cb of LISTENERS[namespace()]) {
25
- await cb(
31
+ const fn = cb.bind(
32
+ null,
26
33
  readableKeys,
27
34
  stateValues,
28
35
  map(realChanges, (k, v) => [
29
- k.slice(NAMESPACE_DELIMITER.length),
36
+ k.slice(namespaceLength),
30
37
  v,
31
38
  ]) as IStateChanges,
32
39
  );
40
+ if (isAsyncFunction(cb)) {
41
+ await fn();
42
+ } else {
43
+ fn();
44
+ }
33
45
  }
34
46
  }
35
47
  }
@@ -39,7 +51,7 @@ export function addStateListener(
39
51
  observables: string[] | IStateListener,
40
52
  cb: () => {},
41
53
  ) {
42
- if (isFunction(observables)) {
54
+ if (isFunction(observables) || isAsyncFunction(observables)) {
43
55
  LISTENERS[namespace()].push(observables as IStateListener);
44
56
  return createStore(namespace());
45
57
  }
@@ -56,7 +68,7 @@ export function removeStateListener(
56
68
  observables: string[] | IStateListener,
57
69
  removeCb: () => {},
58
70
  ) {
59
- if (isFunction(observables)) {
71
+ if (isFunction(observables) || isAsyncFunction(observables)) {
60
72
  const removeIdx = LISTENERS[namespace()].findIndex(
61
73
  (cb) => cb === observables,
62
74
  );
package/src/storage.ts CHANGED
@@ -29,9 +29,16 @@ async function setStorageValue(
29
29
  return false;
30
30
  }
31
31
 
32
+ function removeStorageKey (type: string, key: string) {
33
+ if (type) {
34
+ localStorage.removeItem(key);
35
+ }
36
+ }
37
+
32
38
  export default {
33
39
  GET_TYPE: getStorageType,
34
40
  IS_AVAILABE: isStorageAvailable,
35
41
  UPDATE_STATE: updateFromLocalStorage,
36
42
  SET_VALUES: setStorageValue,
43
+ REMOVE_KEY: removeStorageKey,
37
44
  };
package/src/types.d.ts CHANGED
@@ -29,16 +29,23 @@ type IStorageFunctions = {
29
29
  IS_AVAILABE: (type: string) => boolean;
30
30
  UPDATE_STATE: (state: IStateDefault, type: string) => IStateDefault;
31
31
  SET_VALUES: (type: string, changes: Record<string, any>) => Promise<boolean>;
32
+ REMOVE_KEY: (type: string, key: string) => void;
32
33
  };
33
34
 
34
35
  type IStateListener = (
35
36
  changes: string[],
36
37
  values: Record<string, any>,
37
38
  data: IStateChanges,
38
- ) => {};
39
+ ) => any;
39
40
 
40
41
  type IStateListeners = Record<string, IStateListener[]>;
41
42
 
42
43
  type IStateAction = (mutator: IStateMutator, args: any[]) => void;
43
44
 
44
- type IStateActions = Record<string, IStateAction>;
45
+ type IStateActions = Record<string, IStateAction>;
46
+
47
+ type IStateUpdatePieces = Record<string, {
48
+ storageTypes: Record<string, boolean>;
49
+ readyStorageTypes: Record<string, boolean>;
50
+ changes: IStateChanges;
51
+ }>;
@@ -5,6 +5,7 @@ export default {
5
5
  IS_AVAILABE: isStorageAvailable,
6
6
  UPDATE_STATE: updateStateFromStorage,
7
7
  SET_VALUES: setStorageValue,
8
+ REMOVE_KEY: removeStorageKey,
8
9
  };
9
10
 
10
11
  function getStorageType(isPersistent: boolean) {
@@ -27,6 +28,12 @@ async function setStorageValue(type: string, changes: Record<string, any>) {
27
28
  return true;
28
29
  }
29
30
 
31
+ async function removeStorageKey(type: string, key: string) {
32
+ if (type) {
33
+ await browser.storage[type].remove(key);
34
+ }
35
+ }
36
+
30
37
  export function isSessionStorageSupport() {
31
38
  return !!browser.storage.session;
32
39
  }
@@ -6,12 +6,12 @@ import webextensionStorageUtils, {
6
6
  isSessionStorageSupport,
7
7
  } from "./webextension-storage";
8
8
 
9
- const { onStateChange, setStorageUtils } = main;
9
+ const { joinStateChanges, setStorageUtils } = main;
10
10
 
11
11
  if (isBackgroundScript()) {
12
- browser.storage.local.onChanged.addListener(onStateChange);
12
+ browser.storage.local.onChanged.addListener(joinStateChanges);
13
13
  isSessionStorageSupport() &&
14
- browser.storage.session.onChanged.addListener(onStateChange);
14
+ browser.storage.session.onChanged.addListener(joinStateChanges);
15
15
  }
16
16
 
17
17
  setStorageUtils(webextensionStorageUtils);
package/src/validation.ts DELETED
@@ -1,31 +0,0 @@
1
- import { STATE } from ".";
2
- import { NAMESPACE_DELIMITER } from "./constants";
3
-
4
- function splitFullKey(fullKey: string) {
5
- const segments = fullKey.split(NAMESPACE_DELIMITER);
6
- return [segments.slice(-1)[0], segments.join(NAMESPACE_DELIMITER)];
7
- }
8
-
9
- export const isValid = {
10
- Setting: (fullKey: string) => {
11
- if (!STATE[fullKey]) {
12
- const [key, namespace] = splitFullKey(fullKey);
13
- throw new Error(
14
- `Setting "${key}" key in "${namespace}" namespace. DOES NOT EXIST`,
15
- );
16
- }
17
-
18
- return true;
19
- },
20
-
21
- Defining: (fullKey: string) => {
22
- if (STATE[fullKey]) {
23
- const [key, namespace] = splitFullKey(fullKey);
24
- throw new Error(
25
- `Redefining "${key}" key in "${namespace}" namespace. ALREADY DEFINED`,
26
- );
27
- }
28
-
29
- return true;
30
- },
31
- };