-
-
Notifications
You must be signed in to change notification settings - Fork 178
/
StorageFactory.ts
94 lines (93 loc) · 2.77 KB
/
StorageFactory.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import * as PropertySymbol from '../PropertySymbol.js';
import Storage from './Storage.js';
/**
* Dataset factory.
*
* Reference:
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/storage
*/
export default class StorageFactory {
/**
* Creates a new storage.
*/
public static createStorage(): Storage {
// Documentation for Proxy:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
return new Proxy(new Storage(), {
get(storage: Storage, key: string): string | number | boolean | Function {
if (Storage.prototype.hasOwnProperty(key)) {
const descriptor = Object.getOwnPropertyDescriptor(Storage.prototype, key);
if (descriptor.value !== undefined) {
if (typeof descriptor.value === 'function') {
return storage[key].bind(storage);
}
return descriptor.value;
}
if (descriptor.get) {
return descriptor.get.call(storage);
}
return storage[key];
}
return storage[PropertySymbol.data][key];
},
set(storage: Storage, key: string, value: string): boolean {
if (Storage.prototype.hasOwnProperty(key)) {
return true;
}
storage[PropertySymbol.data][key] = String(value);
return true;
},
deleteProperty(storage: Storage, key: string): boolean {
if (Storage.prototype.hasOwnProperty(key)) {
return true;
}
return delete storage[PropertySymbol.data][key];
},
ownKeys(storage: Storage): string[] {
return Object.keys(storage[PropertySymbol.data]);
},
has(storage: Storage, key: string): boolean {
return storage[PropertySymbol.data][key] !== undefined;
},
defineProperty(storage: Storage, key: string, descriptor: PropertyDescriptor): boolean {
if (Storage.prototype.hasOwnProperty(key)) {
if (descriptor.get || descriptor.set) {
Object.defineProperty(storage, key, {
...descriptor,
get: descriptor.get ? descriptor.get.bind(storage) : undefined,
set: descriptor.set ? descriptor.set.bind(storage) : undefined
});
} else {
Object.defineProperty(storage, key, {
...descriptor,
value:
typeof descriptor.value === 'function'
? descriptor.value.bind(storage)
: descriptor.value
});
}
return true;
}
if (descriptor.value === undefined) {
return false;
}
storage[PropertySymbol.data][key] = String(descriptor.value);
return true;
},
getOwnPropertyDescriptor(storage: Storage, key: string): PropertyDescriptor {
if (
Storage.prototype.hasOwnProperty(key) ||
storage[PropertySymbol.data][key] === undefined
) {
return;
}
return {
value: storage[PropertySymbol.data][key],
writable: true,
enumerable: true,
configurable: false
};
}
});
}
}