@esportsplus/web-storage 0.1.26 → 0.1.27

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
+ filter(fn: Filter<T>): Promise<T>;
15
+ get(key: keyof T): Promise<T[keyof T] | undefined>;
16
+ only(...keys: (keyof T)[]): Promise<T>;
14
17
  replace(values: T): Promise<void>;
15
18
  set(key: keyof T, value: T[keyof T]): Promise<void>;
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,109 @@
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
+ try {
33
+ value = JSON.parse(value);
34
+ }
35
+ catch {
36
+ return undefined;
37
+ }
38
+ }
39
+ return value;
40
+ }
41
+ async serialize(value) {
42
+ if (value === null || value === undefined) {
43
+ return undefined;
44
+ }
45
+ value = JSON.stringify(value);
46
+ if (this.secret) {
47
+ value = await encrypt(value, this.secret);
48
+ }
49
+ return value;
22
50
  }
23
51
  async all() {
24
- let values = {};
25
- await this.instance.iterate((value, key) => {
26
- values[key] = value;
52
+ let stack = [], values = {};
53
+ await this.instance.iterate((v, k) => {
54
+ stack.push(this.deserialize(v).then((value) => {
55
+ if (value === undefined) {
56
+ return;
57
+ }
58
+ values[k] = value;
59
+ }));
27
60
  });
61
+ await Promise.allSettled(stack);
28
62
  return values;
29
63
  }
30
64
  async clear() {
31
65
  await this.instance.clear();
32
66
  }
33
67
  async delete(...keys) {
34
- if (!keys.length) {
35
- return;
36
- }
68
+ let stack = [];
37
69
  for (let i = 0, n = keys.length; i < n; i++) {
38
- await this.instance.removeItem(keys[i]);
70
+ stack.push(this.instance.removeItem(keys[i]));
39
71
  }
72
+ await Promise.allSettled(stack);
40
73
  }
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 })) {
74
+ async filter(fn) {
75
+ let stop = () => {
76
+ stopped = true;
77
+ }, stopped = false, values = {};
78
+ await this.instance.iterate(async (v, k, i) => {
79
+ let key = k, value = await this.deserialize(v);
80
+ if (value === undefined) {
81
+ return;
82
+ }
83
+ if (await fn({ i, key, stop, value })) {
47
84
  values[key] = value;
48
85
  }
49
- if (stop) {
86
+ if (stopped) {
50
87
  return true;
51
88
  }
52
89
  });
53
90
  return values;
54
91
  }
55
92
  async get(key) {
56
- let value = await this.instance.getItem(key);
57
- if (value === null) {
58
- return undefined;
59
- }
60
- return value;
93
+ return await this.deserialize(await this.instance.getItem(key));
61
94
  }
62
95
  async only(...keys) {
63
- return await this.filter((key) => keys.includes(key));
96
+ return await this.filter(({ key }) => keys.includes(key));
64
97
  }
65
98
  async replace(values) {
99
+ let stack = [];
66
100
  for (let key in values) {
67
- await this.instance.setItem(key, values[key]);
101
+ stack.push(this.set(key, values[key]));
68
102
  }
103
+ await Promise.allSettled(stack);
69
104
  }
70
105
  async set(key, value) {
71
- await this.instance.setItem(key, value);
106
+ await this.instance.setItem(key, await this.serialize(value));
72
107
  }
73
108
  }
74
- export default (options) => new Local(options);
109
+ 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,6 +1,7 @@
1
1
  {
2
2
  "author": "ICJR",
3
3
  "dependencies": {
4
+ "@esportsplus/crypto": "^0.0.2",
4
5
  "localforage": "^1.10.0"
5
6
  },
6
7
  "description": "Web storage utility",
@@ -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.27"
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,82 @@ 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
+ try {
44
+ value = JSON.parse(value);
45
+ }
46
+ catch {
47
+ return undefined;
48
+ }
49
+ }
50
+
51
+ return value as T[keyof T];
52
+ }
53
+
54
+ private async serialize(value: unknown) {
55
+ if (value === null || value === undefined) {
56
+ return undefined;
57
+ }
58
+
59
+ value = JSON.stringify(value);
60
+
61
+ if (this.secret) {
62
+ value = await encrypt(value as string, this.secret);
63
+ }
64
+
65
+ return value as string;
30
66
  }
31
67
 
32
68
 
33
- async all(): Promise<T | Record<string, never>> {
34
- let values: T = {} as T;
69
+ async all(): Promise<T> {
70
+ let stack: Promise<void>[] = [],
71
+ values: T = {} as T;
72
+
73
+ await this.instance.iterate((v: unknown, k: string) => {
74
+ stack.push(
75
+ this.deserialize(v).then((value) => {
76
+ if (value === undefined) {
77
+ return;
78
+ }
35
79
 
36
- await this.instance.iterate((value: any, key: string) => {
37
- values[key as keyof T] = value;
80
+ values[k as keyof T] = value;
81
+ })
82
+ )
38
83
  });
39
84
 
85
+ await Promise.allSettled(stack);
86
+
40
87
  return values;
41
88
  }
42
89
 
@@ -45,30 +92,37 @@ class Local<T> {
45
92
  }
46
93
 
47
94
  async delete(...keys: (keyof T)[]) {
48
- if (!keys.length) {
49
- return;
50
- }
95
+ let stack: Promise<void>[] = [];
51
96
 
52
97
  for (let i = 0, n = keys.length; i < n; i++) {
53
- await this.instance.removeItem(keys[i] as string);
98
+ stack.push( this.instance.removeItem(keys[i] as string) );
54
99
  }
100
+
101
+ await Promise.allSettled(stack);
55
102
  }
56
103
 
57
- async filter(filter: Function): Promise<T | Record<string, never>> {
58
- let s: VoidFunction = () => {
59
- stop = true;
104
+ async filter(fn: Filter<T>): Promise<T> {
105
+ let stop: VoidFunction = () => {
106
+ stopped = true;
60
107
  },
61
- stop: boolean = false,
108
+ stopped: boolean = false,
62
109
  values: T = {} as T;
63
110
 
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;
111
+ await this.instance.iterate(async (v, k, i) => {
112
+ let key = k as keyof T,
113
+ value = await this.deserialize(v);
114
+
115
+ if (value === undefined) {
116
+ return;
117
+ }
118
+
119
+ if (await fn({ i, key, stop, value })) {
120
+ values[key] = value;
67
121
  }
68
122
 
69
123
  // LocalForage iterate will stop once a non
70
124
  // undefined value is returned
71
- if (stop) {
125
+ if (stopped) {
72
126
  return true;
73
127
  }
74
128
  });
@@ -77,29 +131,27 @@ class Local<T> {
77
131
  }
78
132
 
79
133
  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;
134
+ return await this.deserialize( await this.instance.getItem(key as string) );
87
135
  }
88
136
 
89
137
  async only(...keys: (keyof T)[]) {
90
- return await this.filter((key: string) => keys.includes(key as keyof T));
138
+ return await this.filter(({ key }) => keys.includes(key));
91
139
  }
92
140
 
93
141
  async replace(values: T) {
142
+ let stack: Promise<void>[] = [];
143
+
94
144
  for (let key in values) {
95
- await this.instance.setItem(key, values[key]);
145
+ stack.push( this.set(key, values[key]) );
96
146
  }
147
+
148
+ await Promise.allSettled(stack);
97
149
  }
98
150
 
99
151
  async set(key: keyof T, value: T[keyof T]) {
100
- await this.instance.setItem(key as string, value);
152
+ await this.instance.setItem(key as string, await this.serialize(value));
101
153
  }
102
154
  }
103
155
 
104
156
 
105
- export default <T>(options: Options) => new Local<T>(options);
157
+ 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
- };