@esportsplus/web-storage 0.3.5 → 0.4.0
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/constants.d.ts +3 -1
- package/build/constants.js +2 -0
- package/build/drivers/memory.d.ts +16 -0
- package/build/drivers/memory.js +64 -0
- package/build/drivers/sessionstorage.d.ts +19 -0
- package/build/drivers/sessionstorage.js +94 -0
- package/build/index.d.ts +12 -2
- package/build/index.js +271 -31
- package/build/types.d.ts +16 -2
- package/package.json +6 -2
- package/src/constants.ts +3 -1
- package/src/drivers/memory.ts +92 -0
- package/src/drivers/sessionstorage.ts +131 -0
- package/src/index.ts +420 -39
- package/src/types.ts +23 -2
- package/storage/feature-research.md +173 -0
- package/tests/drivers/indexeddb.ts +297 -0
- package/tests/drivers/localstorage.ts +290 -0
- package/tests/drivers/memory.ts +257 -0
- package/tests/drivers/sessionstorage.ts +290 -0
- package/tests/index.ts +1462 -0
- package/vitest.config.ts +16 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Driver } from '~/types';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
let stores = new Map<string, Map<unknown, unknown>>();
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MemoryDriver<T> implements Driver<T> {
|
|
8
|
+
|
|
9
|
+
private store: Map<keyof T, T[keyof T]>;
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
constructor(name: string, _version: number) {
|
|
13
|
+
let existing = stores.get(name);
|
|
14
|
+
|
|
15
|
+
if (existing) {
|
|
16
|
+
this.store = existing as Map<keyof T, T[keyof T]>;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
this.store = new Map();
|
|
20
|
+
stores.set(name, this.store as Map<unknown, unknown>);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
async all(): Promise<T> {
|
|
26
|
+
let result = {} as T;
|
|
27
|
+
|
|
28
|
+
for (let [key, value] of this.store) {
|
|
29
|
+
result[key] = value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async clear(): Promise<void> {
|
|
36
|
+
this.store.clear();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async count(): Promise<number> {
|
|
40
|
+
return this.store.size;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async delete(keys: (keyof T)[]): Promise<void> {
|
|
44
|
+
for (let i = 0, n = keys.length; i < n; i++) {
|
|
45
|
+
this.store.delete(keys[i]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async get(key: keyof T): Promise<T[keyof T] | undefined> {
|
|
50
|
+
return this.store.get(key);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async keys(): Promise<(keyof T)[]> {
|
|
54
|
+
return [...this.store.keys()];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async map(fn: (value: T[keyof T], key: keyof T, i: number) => void | Promise<void>): Promise<void> {
|
|
58
|
+
let i = 0;
|
|
59
|
+
|
|
60
|
+
for (let [key, value] of this.store) {
|
|
61
|
+
await fn(value, key, i++);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async only(keys: (keyof T)[]): Promise<Map<keyof T, T[keyof T]>> {
|
|
66
|
+
let results = new Map<keyof T, T[keyof T]>();
|
|
67
|
+
|
|
68
|
+
for (let i = 0, n = keys.length; i < n; i++) {
|
|
69
|
+
let value = this.store.get(keys[i]);
|
|
70
|
+
|
|
71
|
+
if (value !== undefined) {
|
|
72
|
+
results.set(keys[i], value);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return results;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async replace(entries: [keyof T, T[keyof T]][]): Promise<void> {
|
|
80
|
+
for (let i = 0, n = entries.length; i < n; i++) {
|
|
81
|
+
this.store.set(entries[i][0], entries[i][1]);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async set(key: keyof T, value: T[keyof T]): Promise<boolean> {
|
|
86
|
+
this.store.set(key, value);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
export { MemoryDriver };
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { Driver } from '~/types';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SessionStorageDriver<T> implements Driver<T> {
|
|
5
|
+
|
|
6
|
+
private prefix: string;
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
constructor(name: string, version: number) {
|
|
10
|
+
this.prefix = `${name}:${version}:`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
private getKeys(): string[] {
|
|
15
|
+
let keys: string[] = [];
|
|
16
|
+
|
|
17
|
+
for (let i = 0, n = sessionStorage.length; i < n; i++) {
|
|
18
|
+
let key = sessionStorage.key(i);
|
|
19
|
+
|
|
20
|
+
if (key && key.startsWith(this.prefix)) {
|
|
21
|
+
keys.push(key.slice(this.prefix.length));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return keys;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private key(key: keyof T): string {
|
|
29
|
+
return this.prefix + String(key);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private parse(value: string | null): unknown {
|
|
33
|
+
if (value === null) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
return JSON.parse(value);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
async all(): Promise<T> {
|
|
47
|
+
let keys = this.getKeys(),
|
|
48
|
+
result = {} as T;
|
|
49
|
+
|
|
50
|
+
for (let i = 0, n = keys.length; i < n; i++) {
|
|
51
|
+
let value = this.parse(sessionStorage.getItem(this.prefix + keys[i]));
|
|
52
|
+
|
|
53
|
+
if (value !== undefined) {
|
|
54
|
+
result[keys[i] as keyof T] = value as T[keyof T];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async clear(): Promise<void> {
|
|
62
|
+
let keys = this.getKeys();
|
|
63
|
+
|
|
64
|
+
for (let i = 0, n = keys.length; i < n; i++) {
|
|
65
|
+
sessionStorage.removeItem(this.prefix + keys[i]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async count(): Promise<number> {
|
|
70
|
+
return this.getKeys().length;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async delete(keys: (keyof T)[]): Promise<void> {
|
|
74
|
+
for (let i = 0, n = keys.length; i < n; i++) {
|
|
75
|
+
sessionStorage.removeItem(this.key(keys[i]));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async get(key: keyof T): Promise<T[keyof T] | undefined> {
|
|
80
|
+
return this.parse(sessionStorage.getItem(this.key(key))) as T[keyof T] | undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async keys(): Promise<(keyof T)[]> {
|
|
84
|
+
return this.getKeys() as (keyof T)[];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async map(fn: (value: T[keyof T], key: keyof T, i: number) => void | Promise<void>): Promise<void> {
|
|
88
|
+
let keys = this.getKeys();
|
|
89
|
+
|
|
90
|
+
for (let i = 0, n = keys.length; i < n; i++) {
|
|
91
|
+
let value = this.parse(sessionStorage.getItem(this.prefix + keys[i]));
|
|
92
|
+
|
|
93
|
+
if (value !== undefined) {
|
|
94
|
+
await fn(value as T[keyof T], keys[i] as keyof T, i);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async only(keys: (keyof T)[]): Promise<Map<keyof T, T[keyof T]>> {
|
|
100
|
+
let results = new Map<keyof T, T[keyof T]>();
|
|
101
|
+
|
|
102
|
+
for (let i = 0, n = keys.length; i < n; i++) {
|
|
103
|
+
let value = this.parse(sessionStorage.getItem(this.key(keys[i])));
|
|
104
|
+
|
|
105
|
+
if (value !== undefined) {
|
|
106
|
+
results.set(keys[i], value as T[keyof T]);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return results;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async replace(entries: [keyof T, T[keyof T]][]): Promise<void> {
|
|
114
|
+
for (let i = 0, n = entries.length; i < n; i++) {
|
|
115
|
+
sessionStorage.setItem(this.key(entries[i][0]), JSON.stringify(entries[i][1]));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async set(key: keyof T, value: T[keyof T]): Promise<boolean> {
|
|
120
|
+
try {
|
|
121
|
+
sessionStorage.setItem(this.key(key), JSON.stringify(value));
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
export { SessionStorageDriver };
|