varstor 0.6.61 → 0.6.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,26 +4,26 @@ export default {
4
4
  GET_TYPE: getStorageType,
5
5
  IS_AVAILABE: isStorageAvailable,
6
6
  UPDATE_STATE: updateStateFromStorage,
7
- SET_VALUE: setStorageValue,
7
+ SET_VALUES: setStorageValue,
8
8
  };
9
9
 
10
- function getStorageType(isPersistent) {
10
+ function getStorageType(isPersistent: boolean) {
11
11
  return (isBackgroundScript() && isPersistent && "local") || "session";
12
12
  }
13
13
 
14
- function isStorageAvailable(storageType) {
14
+ function isStorageAvailable(storageType: string) {
15
15
  return (
16
16
  storageType === "local" ||
17
17
  (storageType === "session" && isSessionStorageSupport())
18
18
  );
19
19
  }
20
20
 
21
- async function updateStateFromStorage(state, type) {
21
+ async function updateStateFromStorage(state: IStateDefault, type: string) {
22
22
  return Object.assign(state, await browser.storage[type].get());
23
23
  }
24
24
 
25
- async function setStorageValue(type, key, value) {
26
- await browser.storage[type].set({ [key]: value });
25
+ async function setStorageValue(type: string, changes: Record<string, any>) {
26
+ await browser.storage[type].set(changes);
27
27
  return true;
28
28
  }
29
29
 
@@ -1,7 +1,10 @@
1
1
  const browser = require("webextension-polyfill/dist/browser-polyfill.min");
2
2
 
3
- import main from '.';
4
- import webextensionStorageUtils, { isBackgroundScript, isSessionStorageSupport } from './webextension-storage';
3
+ import main from ".";
4
+ import webextensionStorageUtils, {
5
+ isBackgroundScript,
6
+ isSessionStorageSupport,
7
+ } from "./webextension-storage";
5
8
 
6
9
  const { onStateChange, setStorageUtils } = main;
7
10
 
package/tsconfig.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "compilerOptions": {
3
+ "allowSyntheticDefaultImports": true,
4
+ "lib": [
5
+ "dom",
6
+ "dom.iterable",
7
+ "esnext"
8
+ ],
9
+ "strict": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "node",
12
+ "target": "esnext",
13
+ "allowJs": true,
14
+ "skipLibCheck": true,
15
+ "esModuleInterop": true,
16
+ "resolveJsonModule": true,
17
+ "verbatimModuleSyntax": true,
18
+ "erasableSyntaxOnly": true,
19
+ "isolatedModules": true,
20
+ "rewriteRelativeImportExtensions": true,
21
+ "outDir": "./dist",
22
+ "rootDir": ".",
23
+ "ignoreDeprecations": "6.0",
24
+ "types": ["webpack-env"]
25
+ },
26
+ "include": ["./src/**/*"],
27
+ "exclude": ["./node_modules"]
28
+ }
package/webpack.config.js CHANGED
@@ -3,8 +3,8 @@ const MinimizerPlugin = require("minimizer-webpack-plugin");
3
3
  module.exports = (env) => {
4
4
  const options = {
5
5
  entry: {
6
- varstor: "./src/index.js",
7
- "varstor-webextension": "./src/webextension.js",
6
+ varstor: "./src/index.ts",
7
+ "varstor-webextension": "./src/webextension.ts",
8
8
  },
9
9
  output: {
10
10
  filename: ({ chunk }) => `./${chunk.name}.js`,
@@ -20,6 +20,20 @@ module.exports = (env) => {
20
20
  colors: true,
21
21
  },
22
22
 
23
+ module: {
24
+ rules: [
25
+ {
26
+ test: /\.(ts|tsx)$/i,
27
+ loader: "ts-loader",
28
+ exclude: ["/node_modules/"],
29
+ },
30
+ ],
31
+ },
32
+
33
+ resolve: {
34
+ extensions: [".ts", ".js"],
35
+ },
36
+
23
37
  devtool: false,
24
38
  };
25
39
 
package/src/helpers.js DELETED
@@ -1,40 +0,0 @@
1
- const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
2
- const ARGUMENT_NAMES = /([^\s,]+)/g;
3
-
4
- export function isFunction(x) {
5
- return typeof x === "function";
6
- }
7
-
8
- export function isObject(x) {
9
- return Object.prototype.toString.call(x) === "[object Object]";
10
- }
11
-
12
- export function isString(x) {
13
- return typeof x === "string";
14
- }
15
-
16
- export function isArray(x) {
17
- return Array.isArray(x);
18
- }
19
-
20
- export function getParamNames(fn) {
21
- const fnStr = fn.toString().replace(STRIP_COMMENTS, "").split("=>")[0];
22
- const names = fnStr
23
- .slice(fnStr.indexOf("(") + 1, fnStr.indexOf(")"))
24
- .match(ARGUMENT_NAMES);
25
-
26
- if (names === null) {
27
- return [];
28
- }
29
-
30
- return names;
31
- }
32
-
33
- export function getKeys(obj, key) {
34
- return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, v[key]]));
35
- }
36
-
37
- export function toCamelCase(str, delimiter) {
38
- const strArr = str.split(delimiter);
39
- return `${strArr[0]}${strArr.slice(1).reduce((a, c) => `${a}${c.charAt(0).toUpperCase()}${c.slice(1)}`, "")}`;
40
- }
package/src/index.js DELETED
@@ -1,283 +0,0 @@
1
- import storageUtils from './storage';
2
-
3
- import {
4
- isArray, isFunction, isObject, isString,
5
- getParamNames,
6
- getKeys,
7
- } from './helpers';
8
-
9
- import {
10
- addNamespace,
11
- splitFullKey,
12
- namespacify,
13
- getByNamespace,
14
- } from "./namespace";
15
-
16
- import {
17
- isValid
18
- } from './validation';
19
-
20
- const STATE = {};
21
- export const ACCESSORS = {};
22
- const COMPUTED_DEPENDENCIES = {};
23
- const COMPUTED_ARGUMENTS = {};
24
-
25
- const STORAGE = {
26
- GET_TYPE: null,
27
- IS_AVAILABE: null,
28
- UPDATE_STATE: null,
29
- SET_VALUE: null
30
- };
31
-
32
- setStorageUtils(storageUtils);
33
-
34
- async function addState (namespace, initialState, isPersistent) {
35
- const storageType = STORAGE.GET_TYPE(isPersistent);
36
- const defaultValues = Object.assign({}, initialState);
37
- const namespacedValues = namespacify(namespace(), initialState);
38
-
39
- if (STORAGE.IS_AVAILABE(storageType)) {
40
- await STORAGE.UPDATE_STATE(namespacedValues, storageType);
41
- }
42
-
43
- const accessors = {};
44
- for (const key in initialState) {
45
- isValid.Defining(namespace(key));
46
- accessors[namespace(key)] = setupValue(
47
- namespace(key),
48
- namespacedValues[namespace(key)],
49
- defaultValues[key],
50
- storageType,
51
- );
52
- }
53
-
54
- Object.assign(ACCESSORS, accessors);
55
- return createStore(namespace());
56
- }
57
-
58
- function setupValue (key, value, defaultValue, storageType) {
59
- const isComputedValue = isFunction(value);
60
-
61
- if (isComputedValue) {
62
- setupDependencies(key, value);
63
- }
64
-
65
- STATE[key] = {
66
- value: isComputedValue ? value.apply(null, getArguments(key)) : value,
67
- computeFn: value,
68
- listeners: [],
69
- defaultValue,
70
- };
71
-
72
- return createAccessor(key, storageType);
73
- }
74
-
75
- function setupDependencies(computedValueName, computeFn) {
76
- const [, namespace] = splitFullKey(computedValueName);
77
- const paramNames = getParamNames(computeFn).map((name) => addNamespace(namespace, name));
78
- COMPUTED_ARGUMENTS[computedValueName] = paramNames;
79
-
80
- paramNames.forEach((param) => {
81
- if (COMPUTED_DEPENDENCIES[param]) {
82
- COMPUTED_DEPENDENCIES[param].push(computedValueName);
83
- } else {
84
- COMPUTED_DEPENDENCIES[param] = [computedValueName];
85
- }
86
- });
87
- }
88
-
89
- function getArguments(computedName) {
90
- const values = getNamespaceValues(computedName);
91
-
92
- return COMPUTED_ARGUMENTS[computedName]
93
- .map((name) => values[splitFullKey(name)[0]])
94
- .concat(values);
95
- }
96
-
97
- function createAccessor(key, storageType) {
98
- const accessor = () => STATE[key].value;
99
-
100
- Object.assign(accessor, {
101
- valueOf: () => STATE[key].value,
102
- toString: () => STATE[key].value,
103
- set: async (value) => await setValue(key, value, storageType),
104
- onChange: (cb) => STATE[key].listeners.push(cb),
105
- removeListener: (removeCb) =>
106
- (STATE[key].listeners = STATE[key].listeners.filter(
107
- (cb) => cb !== removeCb,
108
- )),
109
- reset: () => setValue(key, STATE[key].defaultValue, storageType),
110
- });
111
-
112
- return new Proxy(accessor, {
113
- get: (target, prop) => {
114
- if (Object.keys(accessor).includes(prop)) {
115
- return target[prop];
116
- }
117
-
118
- return STATE[key].value[prop];
119
- },
120
- });
121
- }
122
-
123
- async function setValue (key, value, storageType) {
124
- if (STORAGE.IS_AVAILABE(storageType)) {
125
- const isAutoUpdate = await STORAGE.SET_VALUE(storageType, key, value);
126
- if (isAutoUpdate) {
127
- return;
128
- }
129
- }
130
-
131
- onStateChange({ [key]: { newValue: value } });
132
- }
133
-
134
- function onStateChange (changes) {
135
- const realChanges = {};
136
-
137
- for (const key in changes) {
138
- const prevValue = STATE[key].value;
139
- const newValue = changes[key].newValue;
140
-
141
- if (prevValue !== newValue) {
142
- STATE[key].value = newValue;
143
- realChanges[key] = { newValue, prevValue };
144
-
145
- updateDependencies(key, realChanges);
146
- }
147
- }
148
-
149
- for (const key in realChanges) {
150
- STATE[key].listeners.forEach(async (cb) => await cb(STATE[key].value, getNamespaceValues(key), realChanges[key]));
151
- }
152
- }
153
-
154
- function updateDependencies (key, realChanges) {
155
- const computedDependencies = COMPUTED_DEPENDENCIES[key];
156
- if (computedDependencies) {
157
- computedDependencies.forEach((name) => {
158
- const prevValue = STATE[name].value;
159
- const newValue = STATE[name].computeFn.apply(null, getArguments(name));
160
- if (prevValue !== newValue) {
161
- STATE[name].value = newValue;
162
- realChanges[name] = { newValue, prevValue };
163
- updateDependencies(name, realChanges);
164
- }
165
- });
166
- }
167
- }
168
-
169
- function getState(namespace, arg) {
170
- if (isString(arg)) {
171
- return createStore(arg);
172
- }
173
-
174
- if (isFunction(arg)) {
175
- return getNamespaceAccessors(namespace(""), arg);
176
- }
177
-
178
- return getNamespaceValues(namespace(""));
179
- }
180
-
181
- function getNamespaceValues(namespace) {
182
- return recreateStructure(getKeys(getByNamespace(namespace, STATE), "value"));
183
- }
184
-
185
- function getNamespaceAccessors (namespace, cb) {
186
- const accessors = getByNamespace(namespace, ACCESSORS);
187
- return cb.call(null, accessors, createStore(namespace()));
188
- }
189
-
190
- async function setState (namespace, changes) {
191
- const noKeys = !Object.keys(changes).length;
192
-
193
- if (noKeys) {
194
- resetAllState();
195
- } else {
196
- for (const [k,v] of Object.entries(changes)) {
197
- isValid.Setting(namespace(k));
198
- await ACCESSORS[namespace(k)].set(v);
199
- };
200
- }
201
-
202
- return createStore(namespace());
203
- }
204
-
205
- function resetAllState (namespace) {
206
- Object.entries(ACCESSORS)
207
- .filter(([k]) => k.startsWith(namespace()))
208
- .forEach((k, { reset }) => reset());
209
-
210
- return createStore(namespace());
211
- }
212
-
213
- function addStateLitener (namespace, observables, cb) {
214
- observables.forEach((key) => ACCESSORS[namespace(key)].onChange(cb));
215
-
216
- return createStore(namespace());
217
- }
218
-
219
- function removeStateListener(namespace, observables, cb) {
220
- observables.forEach((key) =>
221
- ACCESSORS[namespace(key)].removeListener(cb),
222
- );
223
-
224
- return createStore(namespace());
225
- }
226
-
227
- function recreateStructure (value) {
228
- let newValue = value;
229
-
230
- if (isArray(value)) {
231
- newValue = [];
232
- value.forEach((v) => newValue.push(recreateStructure(v)));
233
- return newValue;
234
- }
235
-
236
- if (isObject(value)) {
237
- newValue = {};
238
- for (let key in value) {
239
- newValue[key] = recreateStructure(value[key]);
240
- }
241
- return newValue;
242
- }
243
-
244
- return newValue;
245
- }
246
-
247
- function main () {
248
- const arg1 = arguments[1];
249
-
250
- if (!arg1 || isFunction(arg1) || isString(arg1)) {
251
- return getState.apply(null, arguments);
252
- }
253
-
254
- if (Array.isArray(arg1)) {
255
- return addStateLitener.apply(null, arguments);
256
- }
257
-
258
- if (isObject(arg1)) {
259
- return setState.apply(null, arguments);
260
- }
261
- }
262
-
263
- function setStorageUtils(storageUtils) {
264
- Object.assign(STORAGE, storageUtils);
265
- }
266
-
267
- function createStore (_namespace) {
268
- const namespace = (key) => addNamespace(_namespace, key);
269
-
270
- return Object.assign(main.bind(null, namespace), {
271
- add: (state) => addState(namespace, state, false),
272
- addPersistent: (state) => addState(namespace, state, true),
273
- get: (arg) => getState(namespace, arg),
274
- set: async (changes) => await setState(namespace, changes),
275
- resetAll: () => resetAllState(namespace),
276
- onChange: (keys, cb) => addStateLitener(namespace, keys, cb),
277
- removeListener: (keys, cb) => removeStateListener(namespace, keys, cb),
278
- setStorageUtils,
279
- onStateChange,
280
- });
281
- }
282
-
283
- export default createStore("");
package/src/namespace.js DELETED
@@ -1,35 +0,0 @@
1
- import {
2
- getKeys, isString, toCamelCase
3
- } from './helpers';
4
-
5
- const NAMESPACE_DELIMITER = "::";
6
-
7
- export function addNamespace(namespace, str) {
8
- return `${namespace}${isString(str) && NAMESPACE_DELIMITER || ""}${str || ""}`;
9
- }
10
-
11
- export function splitFullKey (str) {
12
- const segments = str.split(NAMESPACE_DELIMITER);
13
-
14
- return [
15
- segments.slice(-1)[0],
16
- segments.slice(0, -1).join(NAMESPACE_DELIMITER),
17
- ];
18
- }
19
-
20
- export function getByNamespace(str, obj) {
21
- const namespace = splitFullKey(str)[1] + NAMESPACE_DELIMITER;
22
-
23
- return Object.fromEntries(
24
- Object.entries(obj)
25
- .filter(([k, v]) => k.startsWith(namespace))
26
- .map(([k, v]) => [k.slice(namespace.length), v]),
27
- );
28
- }
29
-
30
- export function namespacify (namespace, obj) {
31
- return Object.fromEntries(
32
- Object.entries(obj)
33
- .map(([k,v]) => [addNamespace(namespace, k), v]
34
- ));
35
- }
package/src/storage.js DELETED
@@ -1,31 +0,0 @@
1
- function updateFromLocalStorage(state) {
2
- const stored = {};
3
- for (const key in state) {
4
- const value = localStorage.getItem(key);
5
- if (value !== null) {
6
- stored[key] = value;
7
- }
8
- }
9
-
10
- return Object.assign(state, stored);
11
- }
12
-
13
- function getStorageType(isPersistent) {
14
- return isPersistent && "localStorage";
15
- }
16
-
17
- function isStorageAvailable(storageType) {
18
- return storageType;
19
- }
20
-
21
- async function setStorageValue(storageType, key, value) {
22
- await window.localStorage.setItem(key, value);
23
- return false;
24
- }
25
-
26
- export default {
27
- GET_TYPE: getStorageType,
28
- IS_AVAILABE: isStorageAvailable,
29
- UPDATE_STATE: updateFromLocalStorage,
30
- SET_VALUE: setStorageValue,
31
- };