@esportsplus/web-storage 0.1.26 → 0.1.28

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/build/local.d.ts CHANGED
@@ -1,18 +1,21 @@
1
- import { LocalForage, Options } from './types';
1
+ import { Filter, LocalForage, Options } from './types';
2
2
  declare class Local<T> {
3
3
  instance: LocalForage;
4
4
  iterate: LocalForage['iterate'];
5
5
  keys: LocalForage['keys'];
6
6
  length: LocalForage['length'];
7
- constructor(options: Options);
8
- all(): Promise<T | Record<string, never>>;
7
+ secret: null | string;
8
+ constructor(options: Options, secret?: string);
9
+ private deserialize;
10
+ private serialize;
11
+ all(): Promise<T>;
9
12
  clear(): Promise<void>;
10
13
  delete(...keys: (keyof T)[]): Promise<void>;
11
- filter(filter: Function): Promise<T | Record<string, never>>;
12
- get(key: keyof T): Promise<(T[keyof T] & {}) | undefined>;
13
- only(...keys: (keyof T)[]): Promise<T | Record<string, never>>;
14
- replace(values: T): Promise<void>;
15
- set(key: keyof T, value: T[keyof T]): Promise<void>;
14
+ filter(fn: Filter<T>): Promise<T>;
15
+ get(key: keyof T): Promise<T[keyof T] | undefined>;
16
+ only(...keys: (keyof T)[]): Promise<T>;
17
+ replace(values: T): Promise<string[]>;
18
+ set(key: keyof T, value: T[keyof T]): Promise<boolean>;
16
19
  }
17
- declare const _default: <T>(options: Options) => Local<T>;
20
+ declare const _default: <T>(options: Options, secret?: string) => Local<T>;
18
21
  export default _default;
package/build/local.js CHANGED
@@ -1,74 +1,118 @@
1
1
  import { Driver } from './types';
2
+ import { decrypt, encrypt } from '@esportsplus/crypto';
2
3
  import localforage from 'localforage';
3
4
  class Local {
4
5
  instance;
5
6
  iterate;
6
7
  keys;
7
8
  length;
8
- constructor(options) {
9
- let driver;
9
+ secret = null;
10
+ constructor(options, secret) {
10
11
  switch ((options.driver || Driver.IndexedDB)) {
11
12
  case Driver.LocalStorage:
12
- driver = localforage.LOCALSTORAGE;
13
+ options.driver = localforage.LOCALSTORAGE;
13
14
  break;
14
15
  default:
15
- driver = localforage.INDEXEDDB;
16
+ options.driver = localforage.INDEXEDDB;
16
17
  break;
17
18
  }
18
- this.instance = localforage.createInstance(Object.assign(options, { driver, storeName: options.name }));
19
+ this.instance = localforage.createInstance(Object.assign(options, { storeName: options.name }));
19
20
  this.iterate = this.instance.iterate;
20
21
  this.keys = this.instance.keys;
21
22
  this.length = this.instance.length;
23
+ if (secret) {
24
+ this.secret = secret;
25
+ }
26
+ }
27
+ async deserialize(value) {
28
+ if (this.secret && typeof value === 'string') {
29
+ value = await decrypt(value, this.secret);
30
+ }
31
+ if (typeof value === 'string') {
32
+ value = JSON.parse(value);
33
+ }
34
+ return value;
35
+ }
36
+ async serialize(value) {
37
+ if (value === null || value === undefined) {
38
+ return undefined;
39
+ }
40
+ value = JSON.stringify(value);
41
+ if (this.secret) {
42
+ value = await encrypt(value, this.secret);
43
+ }
44
+ return value;
22
45
  }
23
46
  async all() {
24
- let values = {};
25
- await this.instance.iterate((value, key) => {
26
- values[key] = value;
47
+ let stack = [], values = {};
48
+ await this.instance.iterate((v, k) => {
49
+ stack.push(this.deserialize(v)
50
+ .then((value) => {
51
+ if (value === undefined) {
52
+ return;
53
+ }
54
+ values[k] = value;
55
+ })
56
+ .catch(() => { }));
27
57
  });
58
+ await Promise.allSettled(stack);
28
59
  return values;
29
60
  }
30
61
  async clear() {
31
62
  await this.instance.clear();
32
63
  }
33
64
  async delete(...keys) {
34
- if (!keys.length) {
35
- return;
36
- }
65
+ let stack = [];
37
66
  for (let i = 0, n = keys.length; i < n; i++) {
38
- await this.instance.removeItem(keys[i]);
67
+ stack.push(this.instance.removeItem(keys[i]));
39
68
  }
69
+ await Promise.allSettled(stack);
40
70
  }
41
- async filter(filter) {
42
- let s = () => {
43
- stop = true;
44
- }, stop = false, values = {};
45
- await this.instance.iterate((value, key, i) => {
46
- if (filter({ i, key, stop: s, value })) {
71
+ async filter(fn) {
72
+ let stop = () => {
73
+ stopped = true;
74
+ }, stopped = false, values = {};
75
+ await this.instance.iterate(async (v, k, i) => {
76
+ let key = k, value = await this.deserialize(v).catch(() => undefined);
77
+ if (value === undefined) {
78
+ return;
79
+ }
80
+ if (await fn({ i, key, stop, value })) {
47
81
  values[key] = value;
48
82
  }
49
- if (stop) {
83
+ if (stopped) {
50
84
  return true;
51
85
  }
52
86
  });
53
87
  return values;
54
88
  }
55
89
  async get(key) {
56
- let value = await this.instance.getItem(key);
57
- if (value === null) {
58
- return undefined;
59
- }
60
- return value;
90
+ return await this.deserialize(await this.instance.getItem(key)).catch(() => undefined);
61
91
  }
62
92
  async only(...keys) {
63
- return await this.filter((key) => keys.includes(key));
93
+ return await this.filter(({ key }) => keys.includes(key));
64
94
  }
65
95
  async replace(values) {
96
+ let failed = [], stack = [];
66
97
  for (let key in values) {
67
- await this.instance.setItem(key, values[key]);
98
+ stack.push(this.set(key, values[key])
99
+ .then((ok) => {
100
+ if (ok) {
101
+ return;
102
+ }
103
+ failed.push(key);
104
+ }));
68
105
  }
106
+ await Promise.allSettled(stack);
107
+ return failed;
69
108
  }
70
109
  async set(key, value) {
71
- await this.instance.setItem(key, value);
110
+ let ok = true;
111
+ await this.instance.setItem(key, await this.serialize(value).catch(() => {
112
+ ok = false;
113
+ return undefined;
114
+ }));
115
+ return ok;
72
116
  }
73
117
  }
74
- export default (options) => new Local(options);
118
+ export default (options, secret) => new Local(options, secret);
package/build/types.d.ts CHANGED
@@ -3,6 +3,12 @@ declare enum Driver {
3
3
  IndexedDB = 0,
4
4
  LocalStorage = 1
5
5
  }
6
+ type Filter<T> = (data: {
7
+ i: number;
8
+ key: keyof T;
9
+ stop: VoidFunction;
10
+ value: T[keyof T];
11
+ }) => boolean | Promise<boolean>;
6
12
  type LocalForage = typeof localforage;
7
13
  type Options = {
8
14
  description?: string;
@@ -11,4 +17,4 @@ type Options = {
11
17
  size?: number;
12
18
  version?: number;
13
19
  };
14
- export { Driver, LocalForage, Options };
20
+ export { Driver, Filter, LocalForage, Options };
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "author": "ICJR",
3
3
  "dependencies": {
4
+ "@esportsplus/crypto": "^0.0.4",
4
5
  "localforage": "^1.10.0"
5
6
  },
6
7
  "description": "Web storage utility",
7
8
  "devDependencies": {
8
- "@esportsplus/webpack": "^0.0.81"
9
+ "@esportsplus/webpack": "^0.0.97"
9
10
  },
10
11
  "main": "build/index.js",
11
12
  "name": "@esportsplus/web-storage",
@@ -17,5 +18,5 @@
17
18
  "prepublishOnly": "npm run build"
18
19
  },
19
20
  "types": "build/index.d.ts",
20
- "version": "0.1.26"
21
+ "version": "0.1.28"
21
22
  }
package/src/local.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { Driver, LocalForage, Options } from './types';
1
+ import { Driver, Filter, LocalForage, Options } from '~/types';
2
+ import { decrypt, encrypt } from '@esportsplus/crypto';
2
3
  import localforage from 'localforage';
3
4
 
4
5
 
@@ -7,36 +8,79 @@ class Local<T> {
7
8
  iterate: LocalForage['iterate'];
8
9
  keys: LocalForage['keys'];
9
10
  length: LocalForage['length'];
11
+ secret: null | string = null;
10
12
 
11
13
 
12
- constructor(options: Options) {
13
- let driver;
14
-
14
+ constructor(options: Options, secret?: string) {
15
15
  switch ((options.driver || Driver.IndexedDB) as Driver) {
16
16
  case Driver.LocalStorage:
17
- driver = localforage.LOCALSTORAGE;
17
+ options.driver = localforage.LOCALSTORAGE;
18
18
  break;
19
19
  default:
20
- driver = localforage.INDEXEDDB;
20
+ options.driver = localforage.INDEXEDDB;
21
21
  break;
22
22
  }
23
23
 
24
24
  this.instance = localforage.createInstance(
25
- Object.assign(options, { driver, storeName: options.name })
25
+ Object.assign(options, { storeName: options.name })
26
26
  );
27
27
  this.iterate = this.instance.iterate;
28
28
  this.keys = this.instance.keys;
29
29
  this.length = this.instance.length;
30
+
31
+ if (secret) {
32
+ this.secret = secret;
33
+ }
34
+ }
35
+
36
+
37
+ private async deserialize(value: unknown) {
38
+ if (this.secret && typeof value === 'string') {
39
+ value = await decrypt(value, this.secret);
40
+ }
41
+
42
+ if (typeof value === 'string') {
43
+ value = JSON.parse(value);
44
+ }
45
+
46
+ return value as T[keyof T];
47
+ }
48
+
49
+ private async serialize(value: unknown) {
50
+ if (value === null || value === undefined) {
51
+ return undefined;
52
+ }
53
+
54
+ value = JSON.stringify(value);
55
+
56
+ if (this.secret) {
57
+ value = await encrypt(value as string, this.secret);
58
+ }
59
+
60
+ return value as string;
30
61
  }
31
62
 
32
63
 
33
- async all(): Promise<T | Record<string, never>> {
34
- let values: T = {} as T;
64
+ async all(): Promise<T> {
65
+ let stack: Promise<void>[] = [],
66
+ values: T = {} as T;
35
67
 
36
- await this.instance.iterate((value: any, key: string) => {
37
- values[key as keyof T] = value;
68
+ await this.instance.iterate((v: unknown, k: string) => {
69
+ stack.push(
70
+ this.deserialize(v)
71
+ .then((value) => {
72
+ if (value === undefined) {
73
+ return;
74
+ }
75
+
76
+ values[k as keyof T] = value;
77
+ })
78
+ .catch(() => {})
79
+ )
38
80
  });
39
81
 
82
+ await Promise.allSettled(stack);
83
+
40
84
  return values;
41
85
  }
42
86
 
@@ -45,30 +89,37 @@ class Local<T> {
45
89
  }
46
90
 
47
91
  async delete(...keys: (keyof T)[]) {
48
- if (!keys.length) {
49
- return;
50
- }
92
+ let stack: Promise<void>[] = [];
51
93
 
52
94
  for (let i = 0, n = keys.length; i < n; i++) {
53
- await this.instance.removeItem(keys[i] as string);
95
+ stack.push( this.instance.removeItem(keys[i] as string) );
54
96
  }
97
+
98
+ await Promise.allSettled(stack);
55
99
  }
56
100
 
57
- async filter(filter: Function): Promise<T | Record<string, never>> {
58
- let s: VoidFunction = () => {
59
- stop = true;
101
+ async filter(fn: Filter<T>): Promise<T> {
102
+ let stop: VoidFunction = () => {
103
+ stopped = true;
60
104
  },
61
- stop: boolean = false,
105
+ stopped: boolean = false,
62
106
  values: T = {} as T;
63
107
 
64
- await this.instance.iterate((value: any, key: string, i: number) => {
65
- if (filter({ i, key, stop: s, value })) {
66
- values[key as keyof T] = value;
108
+ await this.instance.iterate(async (v, k, i) => {
109
+ let key = k as keyof T,
110
+ value = await this.deserialize(v).catch(() => undefined);
111
+
112
+ if (value === undefined) {
113
+ return;
114
+ }
115
+
116
+ if (await fn({ i, key, stop, value })) {
117
+ values[key] = value;
67
118
  }
68
119
 
69
120
  // LocalForage iterate will stop once a non
70
121
  // undefined value is returned
71
- if (stop) {
122
+ if (stopped) {
72
123
  return true;
73
124
  }
74
125
  });
@@ -77,29 +128,49 @@ class Local<T> {
77
128
  }
78
129
 
79
130
  async get(key: keyof T) {
80
- let value: T[keyof T] | null = await this.instance.getItem(key as string);
81
-
82
- if (value === null) {
83
- return undefined;
84
- }
85
-
86
- return value;
131
+ return await this.deserialize( await this.instance.getItem(key as string) ).catch(() => undefined);
87
132
  }
88
133
 
89
134
  async only(...keys: (keyof T)[]) {
90
- return await this.filter((key: string) => keys.includes(key as keyof T));
135
+ return await this.filter(({ key }) => keys.includes(key));
91
136
  }
92
137
 
93
138
  async replace(values: T) {
139
+ let failed: string[] = [],
140
+ stack: Promise<void>[] = [];
141
+
94
142
  for (let key in values) {
95
- await this.instance.setItem(key, values[key]);
143
+ stack.push(
144
+ this.set(key, values[key])
145
+ .then((ok) => {
146
+ if (ok) {
147
+ return;
148
+ }
149
+
150
+ failed.push(key);
151
+ })
152
+ );
96
153
  }
154
+
155
+ await Promise.allSettled(stack);
156
+
157
+ return failed;
97
158
  }
98
159
 
99
160
  async set(key: keyof T, value: T[keyof T]) {
100
- await this.instance.setItem(key as string, value);
161
+ let ok = true;
162
+
163
+ await this.instance.setItem(
164
+ key as string,
165
+ await this.serialize(value).catch(() => {
166
+ ok = false;
167
+ return undefined;
168
+ })
169
+ );
170
+
171
+ return ok;
101
172
  }
102
173
  }
103
174
 
104
175
 
105
- export default <T>(options: Options) => new Local<T>(options);
176
+ export default <T>(options: Options, secret?: string) => new Local<T>(options, secret);
package/src/types.ts CHANGED
@@ -6,6 +6,8 @@ enum Driver {
6
6
  LocalStorage
7
7
  };
8
8
 
9
+ type Filter<T> = (data: { i: number, key: keyof T, stop: VoidFunction, value: T[keyof T] }) => boolean | Promise<boolean>;
10
+
9
11
  type LocalForage = typeof localforage;
10
12
 
11
13
  type Options = {
@@ -17,4 +19,4 @@ type Options = {
17
19
  };
18
20
 
19
21
 
20
- export { Driver, LocalForage, Options };
22
+ export { Driver, Filter, LocalForage, Options };
@@ -1,20 +0,0 @@
1
- import { LocalForage, Options } from './types';
2
- declare class Store<T> {
3
- instance: LocalForage;
4
- iterate: LocalForage['iterate'];
5
- keys: LocalForage['keys'];
6
- length: LocalForage['length'];
7
- constructor(options: Options);
8
- all(): Promise<T | Record<string, never>>;
9
- clear(): Promise<void>;
10
- delete(...keys: (keyof T)[]): Promise<void>;
11
- filter(filter: Function): Promise<T | Record<string, never>>;
12
- get(key: keyof T): Promise<(T[keyof T] & {}) | undefined>;
13
- only(...keys: (keyof T)[]): Promise<T | Record<string, never>>;
14
- replace(values: T): Promise<void>;
15
- set(key: keyof T, value: T[keyof T]): Promise<void>;
16
- }
17
- declare const _default: {
18
- store: <T>(options: Options) => Store<T>;
19
- };
20
- export default _default;
@@ -1,76 +0,0 @@
1
- import { Driver } from './types';
2
- import localforage from 'localforage';
3
- class Store {
4
- instance;
5
- iterate;
6
- keys;
7
- length;
8
- constructor(options) {
9
- let driver;
10
- switch ((options.driver || Driver.IndexedDB)) {
11
- case Driver.LocalStorage:
12
- driver = localforage.LOCALSTORAGE;
13
- break;
14
- default:
15
- driver = localforage.INDEXEDDB;
16
- break;
17
- }
18
- this.instance = localforage.createInstance(Object.assign(options, { driver, storeName: options.name }));
19
- this.iterate = this.instance.iterate;
20
- this.keys = this.instance.keys;
21
- this.length = this.instance.length;
22
- }
23
- async all() {
24
- let values = {};
25
- await this.instance.iterate((value, key) => {
26
- values[key] = value;
27
- });
28
- return values;
29
- }
30
- async clear() {
31
- await this.instance.clear();
32
- }
33
- async delete(...keys) {
34
- if (!keys.length) {
35
- return;
36
- }
37
- for (let i = 0, n = keys.length; i < n; i++) {
38
- await this.instance.removeItem(keys[i]);
39
- }
40
- }
41
- async filter(filter) {
42
- let s = () => {
43
- stop = true;
44
- }, stop = false, values = {};
45
- await this.instance.iterate((value, key, i) => {
46
- if (filter({ i, key, stop: s, value })) {
47
- values[key] = value;
48
- }
49
- if (stop) {
50
- return true;
51
- }
52
- });
53
- return values;
54
- }
55
- async get(key) {
56
- let value = await this.instance.getItem(key);
57
- if (value === null) {
58
- return undefined;
59
- }
60
- return value;
61
- }
62
- async only(...keys) {
63
- return await this.filter((key) => keys.includes(key));
64
- }
65
- async replace(values) {
66
- for (let key in values) {
67
- await this.instance.setItem(key, values[key]);
68
- }
69
- }
70
- async set(key, value) {
71
- await this.instance.setItem(key, value);
72
- }
73
- }
74
- export default {
75
- store: (options) => new Store(options)
76
- };
@@ -1,14 +0,0 @@
1
- import localforage from 'localforage';
2
- declare enum Driver {
3
- IndexedDB = 0,
4
- LocalStorage = 1
5
- }
6
- type LocalForage = typeof localforage;
7
- type Options = {
8
- description?: string;
9
- driver?: string | string[];
10
- name: string;
11
- size?: number;
12
- version?: number;
13
- };
14
- export { Driver, LocalForage, Options };
@@ -1,7 +0,0 @@
1
- var Driver;
2
- (function (Driver) {
3
- Driver[Driver["IndexedDB"] = 0] = "IndexedDB";
4
- Driver[Driver["LocalStorage"] = 1] = "LocalStorage";
5
- })(Driver || (Driver = {}));
6
- ;
7
- export { Driver };
@@ -1,16 +0,0 @@
1
- declare class Store<T> {
2
- store: T;
3
- constructor(data: T);
4
- all(): {} & T;
5
- clear(): void;
6
- delete(key: keyof T): void;
7
- filter(filter: Function): Promise<T | Record<string, never>>;
8
- get(key: keyof T): T[keyof T];
9
- only(...keys: (keyof T)[]): T;
10
- replace(values: T): void;
11
- set(key: keyof T, value: T[keyof T]): void;
12
- }
13
- declare const _default: {
14
- store: <T>(data: T) => Store<T>;
15
- };
16
- export default _default;
@@ -1,51 +0,0 @@
1
- class Store {
2
- store;
3
- constructor(data) {
4
- this.store = data;
5
- }
6
- all() {
7
- return Object.assign({}, this.store);
8
- }
9
- clear() {
10
- this.store = {};
11
- }
12
- delete(key) {
13
- delete this.store[key];
14
- }
15
- async filter(filter) {
16
- let s = () => {
17
- stop = true;
18
- }, stop = false, values = {};
19
- for (let key in this.store) {
20
- let value = this.store[key];
21
- if (await filter({ key, stop: s, value })) {
22
- values[key] = value;
23
- }
24
- if (stop) {
25
- break;
26
- }
27
- }
28
- return values;
29
- }
30
- get(key) {
31
- return this.store[key];
32
- }
33
- only(...keys) {
34
- let data = {};
35
- for (let i = 0, n = keys.length; i < n; i++) {
36
- data[keys[i]] = this.store[keys[i]];
37
- }
38
- return data;
39
- }
40
- replace(values) {
41
- for (let key in values) {
42
- this.store[key] = values[key];
43
- }
44
- }
45
- set(key, value) {
46
- this.store[key] = value;
47
- }
48
- }
49
- export default {
50
- store: (data) => new Store(data)
51
- };