Repository navigation
Expand file tree
/
Copy pathclient-storage.js
More file actions
165 lines (151 loc) 路 4.49 KB
/
Copy pathclient-storage.js
File metadata and controls
165 lines (151 loc) 路 4.49 KB
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import BaseStorage from './base-storage.js';
import CookiesStorage from './cookies-storage.js';
import JSStorage from './js-storage.js';
import BrowserStorage from './browser-storage.js';
import { createStore } from './helpers.js';
const isServer = () =>
typeof window === 'undefined' || typeof document === 'undefined';
const debug = (...args) => {
if (typeof console === 'object' && console && console.warn) {
// eslint-disable-next-line no-console
console.warn(...args);
}
};
const mixin = (target, proto) => {
if (!proto || proto === Object.prototype) return;
Object.getOwnPropertyNames(proto).forEach((name) => {
if (name !== 'constructor' && !(name in target)) {
target[name] = proto[name];
}
});
mixin(target, Object.getPrototypeOf(proto));
};
/**
* @locus Client
* @class ClientStorage
* @param {String} [driverName] - Preferred driver: 'localStorage' | 'cookies' | 'js'
* @summary Client storage facade with pluggable drivers (localStorage > cookies > js in-memory). Supports TTL, JSON values, Unicode. Server uses JSStorage.
*/
class ClientStorage {
constructor(driverName) {
this.data = createStore();
this.ttlData = createStore();
let StorageDriver;
this.driverName = driverName;
if (isServer()) {
StorageDriver = JSStorage;
this.driverName = 'js';
} else {
switch (driverName) {
case 'localStorage':
if (BrowserStorage.isSupported()) {
StorageDriver = BrowserStorage;
} else {
debug('ClientStorage is set to "localStorage", but it is not supported on this browser');
}
break;
case 'cookies':
if (CookiesStorage.isSupported()) {
StorageDriver = CookiesStorage;
} else {
debug('ClientStorage is set to "cookies", but CookiesStorage is disabled on this browser');
}
break;
case 'js':
StorageDriver = JSStorage;
this.driverName = 'js';
break;
default:
break;
}
}
if (!StorageDriver) {
if (BrowserStorage.isSupported()) {
this.driverName = 'localStorage';
StorageDriver = BrowserStorage;
} else if (CookiesStorage.isSupported()) {
this.driverName = 'cookies';
StorageDriver = CookiesStorage;
} else {
this.driverName = 'js';
StorageDriver = JSStorage;
}
}
if (this.driverName === 'cookies') {
this.driver = new StorageDriver(this, document.cookie);
} else {
this.driver = new StorageDriver(this);
}
this.TTL_SUFFIX = this.driver.TTL_SUFFIX;
// Mix methods from driver prototype chain (BaseStorage + driver overrides) to preserve API
mixin(this, StorageDriver.prototype);
}
/**
* @locus Client
* @memberOf ClientStorage
* @name set
* @param {String} key - The key of the value to set
* @param {*} value - JSON-serializable value to store
* @param {Number} [ttl] - Optional time-to-live in seconds
* @summary Store a value under key with optional TTL.
* @returns {Boolean}
*/
set(key, value, ttl) {
return this.driver.set(key, value, ttl);
}
/**
* @locus Client
* @memberOf ClientStorage
* @name get
* @param {String} key - The key of the value to read
* @summary Read a stored value by key. Returns undefined if not exists or expired (auto-removes expired).
* @returns {any|undefined}
*/
get(key) {
return this.driver.get(key);
}
/**
* @locus Client
* @memberOf ClientStorage
* @name has
* @param {String} key - The name of the record to check
* @summary Check whether a record key is exists
* @returns {Boolean}
*/
has(key) {
return this.driver.has(key);
}
/**
* @locus Client
* @memberOf ClientStorage
* @name keys
* @summary Returns an array of Strings with all readable keys.
* @returns {[String]}
*/
keys() {
return this.driver.keys();
}
/**
* @locus Client
* @memberOf ClientStorage
* @name remove
* @param {String} [key] - The name of the record to remove. Omit to remove all.
* @summary Remove a single record by key, or all records if no key provided.
* @returns {Boolean}
*/
remove(key) {
return this.driver.remove(key);
}
/**
* @function
* @memberOf ClientStorage
* @name empty
* @summary Empty storage (remove all key/value pairs)
* @returns {Boolean}
*/
empty() {
return this.driver.remove();
}
}
export { BaseStorage, JSStorage, BrowserStorage, CookiesStorage, ClientStorage };
export default ClientStorage;