varstor 0.6.64 → 0.6.66
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 +44 -12
- package/dist/varstor-webextension.js +123 -70
- package/dist/varstor-webextension.min.js +1 -1
- package/dist/varstor.js +126 -71
- package/dist/varstor.min.js +1 -1
- package/package.json +3 -1
- package/src/actions.ts +7 -9
- package/src/helpers.ts +1 -1
- package/src/index.ts +75 -30
- package/src/listeners.ts +19 -20
- package/src/storage.ts +3 -1
- package/src/types.d.ts +38 -11
- package/src/webextension-storage.ts +2 -0
- package/webpack.config.js +6 -2
package/src/index.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type IVarstor,
|
|
3
|
+
type IState,
|
|
4
|
+
type IStateUpdatePieces,
|
|
5
|
+
type IStatePendingChanges,
|
|
6
|
+
type IStorageFunctions,
|
|
7
|
+
type INamespace,
|
|
8
|
+
type IStateDefault,
|
|
9
|
+
type IComputeFunction,
|
|
10
|
+
type IValue,
|
|
11
|
+
type IStateChanges,
|
|
12
|
+
type IStateActions,
|
|
13
|
+
type IStateListener,
|
|
14
|
+
} from "./types.d";
|
|
15
|
+
|
|
1
16
|
import storageUtils from "./storage";
|
|
2
17
|
|
|
3
18
|
import {
|
|
@@ -11,6 +26,7 @@ import {
|
|
|
11
26
|
recreateStructure,
|
|
12
27
|
forEach,
|
|
13
28
|
uid,
|
|
29
|
+
isAsyncFunction,
|
|
14
30
|
} from "./helpers";
|
|
15
31
|
|
|
16
32
|
import { addStateActions } from "./actions";
|
|
@@ -25,7 +41,8 @@ import {
|
|
|
25
41
|
} from "./listeners";
|
|
26
42
|
|
|
27
43
|
export const STATE = {} as IState;
|
|
28
|
-
const
|
|
44
|
+
const STATE_CHANGED_PIECES = {} as IStateUpdatePieces;
|
|
45
|
+
const STATE_PENDING_CHANGES = {} as IStatePendingChanges;
|
|
29
46
|
const STORAGE = {} as IStorageFunctions;
|
|
30
47
|
|
|
31
48
|
setStorageUtils(storageUtils);
|
|
@@ -46,10 +63,6 @@ async function addState(
|
|
|
46
63
|
await STORAGE.UPDATE_STATE(values, storageType as string);
|
|
47
64
|
}
|
|
48
65
|
|
|
49
|
-
if (!LISTENERS[namespace()]) {
|
|
50
|
-
LISTENERS[namespace()] = [];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
66
|
for (const key in initialState) {
|
|
54
67
|
const fullKey = namespace(key);
|
|
55
68
|
STATE[fullKey] = setupValue(
|
|
@@ -129,7 +142,7 @@ export async function joinStateChanges(changesPiece: IStateChanges) {
|
|
|
129
142
|
for (const [
|
|
130
143
|
updateId,
|
|
131
144
|
{ storageTypes, readyStorageTypes, changes },
|
|
132
|
-
] of Object.entries(
|
|
145
|
+
] of Object.entries(STATE_CHANGED_PIECES)) {
|
|
133
146
|
if (changesPiece[updateId]) {
|
|
134
147
|
const storageType = changesPiece[updateId].newValue;
|
|
135
148
|
readyStorageTypes[storageType] = true;
|
|
@@ -145,7 +158,7 @@ export async function joinStateChanges(changesPiece: IStateChanges) {
|
|
|
145
158
|
}
|
|
146
159
|
}
|
|
147
160
|
|
|
148
|
-
delete
|
|
161
|
+
delete STATE_CHANGED_PIECES[updateId];
|
|
149
162
|
|
|
150
163
|
await onStateChange(changes);
|
|
151
164
|
}
|
|
@@ -226,13 +239,13 @@ export function getState(namespace: INamespace, arg: string) {
|
|
|
226
239
|
return createStore(arg);
|
|
227
240
|
}
|
|
228
241
|
|
|
229
|
-
return recreateStructure(getValues(namespace))
|
|
242
|
+
return recreateStructure(getValues(namespace)) as Record<string, any>;
|
|
230
243
|
}
|
|
231
244
|
|
|
232
245
|
export async function setState(
|
|
233
246
|
namespace: INamespace,
|
|
234
247
|
changes: Record<string, unknown>,
|
|
235
|
-
): Promise<
|
|
248
|
+
): Promise<IVarstor> {
|
|
236
249
|
const storageChanges: Record<string, any> = {};
|
|
237
250
|
const updateId = uid();
|
|
238
251
|
const storageTypes = {} as Record<string, boolean>;
|
|
@@ -254,7 +267,7 @@ export async function setState(
|
|
|
254
267
|
storageChanges[storageType!][fullKey] = v;
|
|
255
268
|
});
|
|
256
269
|
|
|
257
|
-
|
|
270
|
+
STATE_CHANGED_PIECES[updateId] = {
|
|
258
271
|
storageTypes,
|
|
259
272
|
readyStorageTypes: {},
|
|
260
273
|
changes: {},
|
|
@@ -284,27 +297,51 @@ async function setValues(
|
|
|
284
297
|
}
|
|
285
298
|
|
|
286
299
|
export async function resetState(namespace: INamespace, keys?: string[]) {
|
|
300
|
+
return setState(namespace, getDefaultValues(namespace, keys));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function getDefaultValues(namespace: INamespace, keys?: string[]) {
|
|
287
304
|
const namespaceState = getNamespaceState(namespace);
|
|
288
305
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
) as Record<string, any>,
|
|
297
|
-
);
|
|
306
|
+
return map(
|
|
307
|
+
keys
|
|
308
|
+
? filter(namespaceState, (k, { key }) => keys.includes(key!))
|
|
309
|
+
: namespaceState,
|
|
310
|
+
(k, { key, defaultValue }) => [key, defaultValue],
|
|
311
|
+
) as Record<string, any>;
|
|
312
|
+
}
|
|
298
313
|
|
|
299
|
-
|
|
314
|
+
export function createPendingChanges(namespace: INamespace) {
|
|
315
|
+
const flush = () => {
|
|
316
|
+
const changes = STATE_PENDING_CHANGES[namespace()];
|
|
317
|
+
STATE_PENDING_CHANGES[namespace()] = {};
|
|
318
|
+
return changes;
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
return {
|
|
322
|
+
add: (changes: Record<string, any>) =>
|
|
323
|
+
Object.assign(STATE_PENDING_CHANGES[namespace()], changes),
|
|
324
|
+
reset: (keys: string[]) =>
|
|
325
|
+
Object.assign(
|
|
326
|
+
STATE_PENDING_CHANGES[namespace()],
|
|
327
|
+
getDefaultValues(namespace, keys),
|
|
328
|
+
),
|
|
329
|
+
get: () => STATE_PENDING_CHANGES[namespace()],
|
|
330
|
+
flush,
|
|
331
|
+
commit: () => setState(namespace, flush()),
|
|
332
|
+
};
|
|
300
333
|
}
|
|
301
334
|
|
|
302
|
-
function main(namespace
|
|
335
|
+
function main(namespace?: INamespace): any {
|
|
303
336
|
if (!arguments[1] || isString(arguments[1])) {
|
|
304
337
|
return getState.apply(null, arguments as unknown as [INamespace, string]);
|
|
305
338
|
}
|
|
306
339
|
|
|
307
|
-
if (
|
|
340
|
+
if (
|
|
341
|
+
isArray(arguments[1]) ||
|
|
342
|
+
isFunction(arguments[1]) ||
|
|
343
|
+
isAsyncFunction(arguments[1])
|
|
344
|
+
) {
|
|
308
345
|
return addStateListener.apply(
|
|
309
346
|
null,
|
|
310
347
|
arguments as unknown as [INamespace, string[], () => {}],
|
|
@@ -327,21 +364,29 @@ function addNamespace(namespace: string, str: string) {
|
|
|
327
364
|
return `${namespace}${(isString(str) && NAMESPACE_DELIMITER) || ""}${str || ""}`;
|
|
328
365
|
}
|
|
329
366
|
|
|
330
|
-
export function createStore(_namespace: string) {
|
|
367
|
+
export function createStore(_namespace: string): IVarstor {
|
|
331
368
|
const namespace = ((key: string) =>
|
|
332
369
|
addNamespace(_namespace, key)) as INamespace;
|
|
333
370
|
|
|
371
|
+
if (!STATE_PENDING_CHANGES[namespace()]) {
|
|
372
|
+
STATE_PENDING_CHANGES[namespace()] = {};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if (!LISTENERS[namespace()]) {
|
|
376
|
+
LISTENERS[namespace()] = [];
|
|
377
|
+
}
|
|
378
|
+
|
|
334
379
|
return Object.assign(main.bind(null, namespace), {
|
|
335
380
|
add: (state: IStateDefault) => addState(namespace, state, false),
|
|
336
381
|
addPersistent: (state: IStateDefault) => addState(namespace, state, true),
|
|
337
|
-
get: (newNamespace
|
|
338
|
-
set:
|
|
339
|
-
await setState(namespace, changes),
|
|
382
|
+
get: (newNamespace?: string) => getState(namespace, newNamespace!),
|
|
383
|
+
set: (changes: Record<string, unknown>) => setState(namespace, changes),
|
|
340
384
|
reset: (keys: string[]) => resetState(namespace, keys),
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
385
|
+
changes: createPendingChanges(namespace),
|
|
386
|
+
onChange: (keys: string[] | IStateListener, cb?: IStateListener) =>
|
|
387
|
+
addStateListener(namespace, keys, cb!),
|
|
388
|
+
removeListener: (keys: string[] | IStateListener, cb?: IStateListener) =>
|
|
389
|
+
removeStateListener(namespace, keys, cb!),
|
|
345
390
|
actions: (actions: IStateActions) => addStateActions(namespace, actions),
|
|
346
391
|
setStorageUtils,
|
|
347
392
|
joinStateChanges,
|
package/src/listeners.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type INamespace,
|
|
3
|
+
type IStateListeners,
|
|
4
|
+
type IStateChanges,
|
|
5
|
+
type IStateListener,
|
|
6
|
+
type IValue,
|
|
7
|
+
} from "./types";
|
|
8
|
+
|
|
9
|
+
import { STATE, createStore } from ".";
|
|
2
10
|
import { NAMESPACE_DELIMITER } from "./constants";
|
|
3
11
|
import { map, isFunction, isAsyncFunction } from "./helpers";
|
|
4
12
|
|
|
@@ -6,14 +14,13 @@ export const LISTENERS = {} as IStateListeners;
|
|
|
6
14
|
|
|
7
15
|
export async function runStateChangeListeners(realChanges: IStateChanges) {
|
|
8
16
|
if (Object.keys(realChanges).length) {
|
|
9
|
-
const { namespace } =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
for (let [changeKey, change] of Object.entries(realChanges)) {
|
|
17
|
+
const { namespace } = STATE[
|
|
18
|
+
Object.keys(realChanges)[0] as keyof typeof STATE
|
|
19
|
+
] as IValue;
|
|
20
|
+
for (const [changeKey] of Object.entries(realChanges)) {
|
|
14
21
|
const { listeners, key } = STATE[changeKey];
|
|
15
22
|
for (const cb of listeners!) {
|
|
16
|
-
const fn = cb.bind(null, [key],
|
|
23
|
+
const fn = cb.bind(null, [key!], createStore(namespace()));
|
|
17
24
|
if (isAsyncFunction(cb)) {
|
|
18
25
|
await fn();
|
|
19
26
|
} else {
|
|
@@ -28,15 +35,7 @@ export async function runStateChangeListeners(realChanges: IStateChanges) {
|
|
|
28
35
|
) as string[];
|
|
29
36
|
|
|
30
37
|
for (const cb of LISTENERS[namespace()]) {
|
|
31
|
-
const fn = cb.bind(
|
|
32
|
-
null,
|
|
33
|
-
readableKeys,
|
|
34
|
-
stateValues,
|
|
35
|
-
map(realChanges, (k, v) => [
|
|
36
|
-
k.slice(namespaceLength),
|
|
37
|
-
v,
|
|
38
|
-
]) as IStateChanges,
|
|
39
|
-
);
|
|
38
|
+
const fn = cb.bind(null, readableKeys, createStore(namespace()));
|
|
40
39
|
if (isAsyncFunction(cb)) {
|
|
41
40
|
await fn();
|
|
42
41
|
} else {
|
|
@@ -49,7 +48,7 @@ export async function runStateChangeListeners(realChanges: IStateChanges) {
|
|
|
49
48
|
export function addStateListener(
|
|
50
49
|
namespace: INamespace,
|
|
51
50
|
observables: string[] | IStateListener,
|
|
52
|
-
cb:
|
|
51
|
+
cb: IStateListener,
|
|
53
52
|
) {
|
|
54
53
|
if (isFunction(observables) || isAsyncFunction(observables)) {
|
|
55
54
|
LISTENERS[namespace()].push(observables as IStateListener);
|
|
@@ -66,7 +65,7 @@ export function addStateListener(
|
|
|
66
65
|
export function removeStateListener(
|
|
67
66
|
namespace: INamespace,
|
|
68
67
|
observables: string[] | IStateListener,
|
|
69
|
-
removeCb:
|
|
68
|
+
removeCb: IStateListener,
|
|
70
69
|
) {
|
|
71
70
|
if (isFunction(observables) || isAsyncFunction(observables)) {
|
|
72
71
|
const removeIdx = LISTENERS[namespace()].findIndex(
|
|
@@ -78,8 +77,8 @@ export function removeStateListener(
|
|
|
78
77
|
|
|
79
78
|
(observables as string[]).forEach((key) => {
|
|
80
79
|
const listeners = STATE[namespace(key)].listeners;
|
|
81
|
-
const removeIdx = listeners?.findIndex((cb) => cb === removeCb)
|
|
82
|
-
listeners?.splice(removeIdx
|
|
80
|
+
const removeIdx = listeners?.findIndex((cb) => cb === removeCb);
|
|
81
|
+
listeners?.splice(removeIdx!, 1);
|
|
83
82
|
});
|
|
84
83
|
|
|
85
84
|
return createStore(namespace());
|
package/src/storage.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type IStateDefault } from "./types";
|
|
2
|
+
|
|
1
3
|
async function updateFromLocalStorage(state: IStateDefault) {
|
|
2
4
|
const stored = {} as IStateDefault;
|
|
3
5
|
for (const key in state) {
|
|
@@ -29,7 +31,7 @@ async function setStorageValue(
|
|
|
29
31
|
return false;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
function removeStorageKey
|
|
34
|
+
function removeStorageKey(type: string, key: string) {
|
|
33
35
|
if (type) {
|
|
34
36
|
localStorage.removeItem(key);
|
|
35
37
|
}
|
package/src/types.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ type IValue = {
|
|
|
11
11
|
dependencies?: string[];
|
|
12
12
|
dependants?: string[];
|
|
13
13
|
storageType?: string;
|
|
14
|
-
listeners?:
|
|
14
|
+
listeners?: IStateListener[];
|
|
15
15
|
defaultValue?: any;
|
|
16
16
|
namespace: INamespace;
|
|
17
17
|
};
|
|
@@ -32,11 +32,7 @@ type IStorageFunctions = {
|
|
|
32
32
|
REMOVE_KEY: (type: string, key: string) => void;
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
type IStateListener = (
|
|
36
|
-
changes: string[],
|
|
37
|
-
values: Record<string, any>,
|
|
38
|
-
data: IStateChanges,
|
|
39
|
-
) => any;
|
|
35
|
+
type IStateListener = (changes: string[], store: IStore) => void;
|
|
40
36
|
|
|
41
37
|
type IStateListeners = Record<string, IStateListener[]>;
|
|
42
38
|
|
|
@@ -44,8 +40,39 @@ type IStateAction = (mutator: IStateMutator, args: any[]) => void;
|
|
|
44
40
|
|
|
45
41
|
type IStateActions = Record<string, IStateAction>;
|
|
46
42
|
|
|
47
|
-
type IStateUpdatePieces = Record<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
43
|
+
type IStateUpdatePieces = Record<
|
|
44
|
+
string,
|
|
45
|
+
{
|
|
46
|
+
storageTypes: Record<string, boolean>;
|
|
47
|
+
readyStorageTypes: Record<string, boolean>;
|
|
48
|
+
changes: IStateChanges;
|
|
49
|
+
}
|
|
50
|
+
>;
|
|
51
|
+
|
|
52
|
+
type IStatePendingChanges = Record<string, Record<string, any>>;
|
|
53
|
+
|
|
54
|
+
type IStatePendingChangesFunctions = {
|
|
55
|
+
add: (changes: Record<string, any>) => Record<string, any>;
|
|
56
|
+
reset: (keys: string[]) => Record<string, any>;
|
|
57
|
+
get: () => Record<string, any>;
|
|
58
|
+
flush: () => Record<string, any>;
|
|
59
|
+
commit: () => Promise<unknown>;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export type IVarstor = ((namespace?: INamespace) => any) & {
|
|
63
|
+
add: (state: IStateDefault) => Promise<IVarstor>;
|
|
64
|
+
addPersistent: (state: IStateDefault) => Promise<IVarstor>;
|
|
65
|
+
get: (newNamespace?: string) => IVarstor | Record<string, any>;
|
|
66
|
+
set: (changes: Record<string, unknown>) => Promise<IVarstor>;
|
|
67
|
+
reset: (keys: string[]) => Promise<IVarstor>;
|
|
68
|
+
changes: IStatePendingChangesFunctions;
|
|
69
|
+
onChange: (keys: string[] | IStateListener, cb?: IStateListener) => IVarstor;
|
|
70
|
+
removeListener: (
|
|
71
|
+
keys: string[] | IStateListener,
|
|
72
|
+
cb?: IStateListener,
|
|
73
|
+
) => IVarstor;
|
|
74
|
+
actions: (actions: IStateActions) => IVarstor;
|
|
75
|
+
setStorageUtils: (storageUtils: IStorageFunctions) => void;
|
|
76
|
+
joinStateChanges: (changesPiece: IStateChanges) => Promise<unknown>;
|
|
77
|
+
namespace: INamespace;
|
|
78
|
+
};
|
package/webpack.config.js
CHANGED
|
@@ -25,13 +25,17 @@ module.exports = (env) => {
|
|
|
25
25
|
{
|
|
26
26
|
test: /\.(ts|tsx)$/i,
|
|
27
27
|
loader: "ts-loader",
|
|
28
|
-
exclude:
|
|
28
|
+
exclude: /node_modules|\.d\.ts$/,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
test: /\.d\.ts$/,
|
|
32
|
+
loader: "ignore-loader",
|
|
29
33
|
},
|
|
30
34
|
],
|
|
31
35
|
},
|
|
32
36
|
|
|
33
37
|
resolve: {
|
|
34
|
-
extensions: [".ts", ".js"],
|
|
38
|
+
extensions: [".ts", ".js", ".d.ts"],
|
|
35
39
|
},
|
|
36
40
|
|
|
37
41
|
devtool: false,
|