ClientStorage
Advanced tools
Comparing version 3.0.1 to 4.0.0
'use strict'; | ||
var DEFAULT_TTL = 3.154e+8; // 10 years | ||
var TTL_SUFFIX = '.___exp'; | ||
var TTL_SUFFIX_LENGTH = TTL_SUFFIX.length; | ||
var CookiesStorage = require('./cookies-storage.js'); | ||
var JSStorage = require('./js-storage.js'); | ||
var BrowserStorage = require('./browser-storage.js'); | ||
/* | ||
* @locus Client | ||
* @class __Cookies | ||
* @param _cookies {String} - Current cookies as String | ||
* @summary Internal Class | ||
*/ | ||
function __Cookies(_cookies) { | ||
this.cookies = {}; | ||
if (_cookies && typeof _cookies === 'string') { | ||
this.init(_cookies); | ||
} | ||
} | ||
/* | ||
* @locus Client | ||
* @memberOf __Cookies | ||
* @name init | ||
* @param _cookies {String} - Current cookies as String | ||
* @summary parse document.cookie string | ||
* @returns {void 0} | ||
*/ | ||
__Cookies.prototype.init = function (_cookies) { | ||
if (_cookies && _cookies.length) { | ||
var self = this; | ||
var i; | ||
var key; | ||
var val; | ||
_cookies.split(/; */).forEach(function (pair) { | ||
i = pair.indexOf('='); | ||
if (i < 0) { | ||
return; | ||
} | ||
key = unescape(pair.substr(0, i).trim()); | ||
val = pair.substr(++i, pair.length).trim(); | ||
if (val[0] === '"') { | ||
val = val.slice(1, -1); | ||
} | ||
if (self.cookies[key] === void 0) { | ||
try { | ||
self.cookies[key] = unescape(val); | ||
} catch (e) { | ||
self.cookies[key] = val; | ||
} | ||
} | ||
}); | ||
} | ||
var debug = function () { | ||
console.warn.apply(console, arguments); | ||
}; | ||
/* | ||
/** | ||
* @locus Client | ||
* @memberOf __Cookies | ||
* @name get | ||
* @param {String} key - The name of the cookie to read | ||
* @summary Read a cookie. If the cookie doesn't exist a void 0 (undefined) value will be returned. | ||
* @returns {String|void 0} | ||
*/ | ||
__Cookies.prototype.get = function (key) { | ||
if (!key) { | ||
return void 0; | ||
} | ||
if (this.cookies.hasOwnProperty(key)) { | ||
if (this.cookies.hasOwnProperty(key + TTL_SUFFIX)) { | ||
var expireAt = this.cookies[key + TTL_SUFFIX]; | ||
console.log({expireAt}); | ||
if (expireAt && expireAt <= Date.now()) { | ||
this.remove(key); | ||
return void 0; | ||
} | ||
} | ||
return this.cookies[key]; | ||
} | ||
return void 0; | ||
}; | ||
/* | ||
* @locus Client | ||
* @memberOf __Cookies | ||
* @name set | ||
* @param {String} key - The name of the cookie to create/overwrite | ||
* @param {String} value - The value of the cookie | ||
* @param {Number} ttl - Cookies TTL (e.g. max-age) in seconds | ||
* @summary Create/overwrite a cookie. | ||
* @returns {Boolean} | ||
*/ | ||
__Cookies.prototype.set = function (key, value, ttl) { | ||
if (!ttl) { | ||
ttl = DEFAULT_TTL; | ||
} | ||
if (key) { | ||
this.cookies[key] = value; | ||
document.cookie = escape(key) + '=' + escape(value) + '; Max-Age=' + ttl + '; Path=/'; | ||
if (ttl !== DEFAULT_TTL) { | ||
var expireAt = +(new Date(Date.now() + (ttl * 1000))); | ||
this.cookies[key + TTL_SUFFIX] = expireAt; | ||
document.cookie = escape(key + TTL_SUFFIX) + '=' + expireAt + '; Max-Age=' + ttl + '; Path=/'; | ||
} | ||
return true; | ||
} | ||
return false; | ||
}; | ||
/* | ||
* @locus Client | ||
* @memberOf __Cookies | ||
* @name remove | ||
* @param {String} key - The name of the cookie to remove | ||
* @summary Remove a cookie(s). | ||
* @returns {Boolean} | ||
*/ | ||
__Cookies.prototype.remove = function (key) { | ||
if (key) { | ||
if (!this.cookies.hasOwnProperty(key)) { | ||
return false; | ||
} | ||
delete this.cookies[key]; | ||
delete this.cookies[key + TTL_SUFFIX]; | ||
document.cookie = escape(key) + '=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/'; | ||
document.cookie = escape(key + TTL_SUFFIX) + '=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/'; | ||
return true; | ||
} else if (key === void 0) { | ||
var keys = Object.keys(this.cookies); | ||
if (keys.length > 0 && keys[0] !== '') { | ||
for (var i = 0; i < keys.length; i++) { | ||
this.remove(keys[i]); | ||
} | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
/* | ||
* @locus Client | ||
* @memberOf __Cookies | ||
* @name has | ||
* @param {String} key - The name of the cookie to check | ||
* @summary Check whether a cookie key is exists | ||
* @returns {Boolean} | ||
*/ | ||
__Cookies.prototype.has = function (key) { | ||
if (!key) { | ||
return false; | ||
} | ||
return this.cookies.hasOwnProperty(key); | ||
}; | ||
/* | ||
* @locus Client | ||
* @memberOf __Cookies | ||
* @name keys | ||
* @summary Returns an array of Strings with all readable cookies from this location. | ||
* @returns {[String]} | ||
*/ | ||
__Cookies.prototype.keys = function () { | ||
return Object.keys(this.cookies); | ||
}; | ||
/* | ||
* @locus Client | ||
* @class ClientStorage | ||
* @param driver {Sting} - Preferable driver `localStorage` or `cookies` | ||
* @summary Implement boilerplate Client storage functions, localStorage with fall-back to Cookies | ||
* @param driverName {Sting} - Preferable driver `localStorage` or `cookies` | ||
* @summary Implement boilerplate Client storage functions, localStorage with fall-back to CookiesStorage | ||
*/ | ||
function ClientStorage(driver) { | ||
this._data = {}; | ||
if (navigator.cookieEnabled) { | ||
this.cookies = new __Cookies(document.cookie); | ||
} else { | ||
this.cookies = false; | ||
} | ||
function ClientStorage(driverName) { | ||
this.data = {}; | ||
this.ttlData = {}; | ||
var StorageDriver; | ||
this.driverName = driverName; | ||
switch (driver) { | ||
switch (driverName) { | ||
case 'localStorage': | ||
if (this.LSSupport) { | ||
this.ls = window.localStorage || localStorage; | ||
var i = this.ls.length; | ||
var key; | ||
while (i--) { | ||
key = this.ls.key(i); | ||
if ((key.indexOf(TTL_SUFFIX, key.length - TTL_SUFFIX_LENGTH) !== -1) && this.ls.getItem(key) <= Date.now()) { | ||
this.ls.removeItem(key); | ||
this.ls.removeItem(key.replace(TTL_SUFFIX, '')); | ||
} | ||
} | ||
if (BrowserStorage.isSupported()) { | ||
StorageDriver = BrowserStorage; | ||
} else { | ||
console.warn('ClientStorage is set to "localStorage", but it is not supported on this browser'); | ||
debug('ClientStorage is set to "localStorage", but it is not supported on this browser'); | ||
} | ||
break; | ||
case 'cookies': | ||
if (this.cookies) { | ||
this.LSSupport = false; | ||
this.ls = null; | ||
if (CookiesStorage.isSupported()) { | ||
StorageDriver = CookiesStorage; | ||
} else { | ||
console.warn('ClientStorage is set to "cookies", but Cookies is disabled on this browser'); | ||
debug('ClientStorage is set to "cookies", but CookiesStorage is disabled on this browser'); | ||
} | ||
break; | ||
case 'js': | ||
this.cookies = false; | ||
this.LSSupport = false; | ||
this.ls = null; | ||
StorageDriver = JSStorage; | ||
this.driverName = 'js'; | ||
break; | ||
default: | ||
if (this.LSSupport) { | ||
this.ls = window.localStorage || localStorage; | ||
break; | ||
} | ||
if (!StorageDriver) { | ||
if (BrowserStorage.isSupported()) { | ||
this.driverName = 'localStorage'; | ||
StorageDriver = BrowserStorage; | ||
} else if (CookiesStorage.isSupported()) { | ||
this.driverName = 'cookies'; | ||
StorageDriver = CookiesStorage; | ||
} else { | ||
this.ls = null; | ||
this.driverName = 'js'; | ||
StorageDriver = JSStorage; | ||
} | ||
break; | ||
} | ||
this.driver = new StorageDriver(this, document.cookie); | ||
Object.assign(this, StorageDriver.prototype); | ||
} | ||
/* | ||
* @function | ||
/** | ||
* @locus Client | ||
* @memberOf ClientStorage | ||
* @name get | ||
* @param {String} key - The name of the stored record to read | ||
* @summary Read a record. If the record doesn't exist a null value will be returned. | ||
* @returns {mixed} | ||
* @param {String} key - The key of the value to read | ||
* @summary Read a stored value by key. If the key doesn't exist a void 0 (undefined) value will be returned. | ||
* @returns {String|Mix|void 0} | ||
*/ | ||
ClientStorage.prototype.get = function (key) { | ||
if (!this.has(key)) { | ||
if (typeof key !== 'string') { | ||
return void 0; | ||
} | ||
var expireAt = 0; | ||
if (this.LSSupport) { | ||
expireAt = this.__unescape(this.ls.getItem(key + TTL_SUFFIX)); | ||
if (expireAt && expireAt <= Date.now()) { | ||
this.ls.removeItem(key); | ||
this.ls.removeItem(key + TTL_SUFFIX); | ||
if (this.data.hasOwnProperty(key)) { | ||
if (this.ttlData[key] <= Date.now()) { | ||
this.remove(key); | ||
return void 0; | ||
} | ||
return this.__unescape(this.ls.getItem(key)); | ||
} else if (this.cookies) { | ||
return this.__unescape(this.cookies.get(key)); | ||
return this.data[key]; | ||
} | ||
expireAt = this._data[key + TTL_SUFFIX]; | ||
if (expireAt && expireAt <= Date.now()) { | ||
delete this._data[key]; | ||
delete this._data[key + TTL_SUFFIX]; | ||
return void 0; | ||
} | ||
return this._data[key]; | ||
return void 0; | ||
}; | ||
/* | ||
* @function | ||
/** | ||
* @locus Client | ||
* @memberOf ClientStorage | ||
* @name set | ||
* @param {String} key - The name of the key to create/overwrite | ||
* @param {mixed} value - The value | ||
* @param {Number} ttl - [OPTIONAL] Record TTL in seconds | ||
* @summary Create/overwrite a value in storage. | ||
* @name has | ||
* @param {String} key - The name of the record to check | ||
* @summary Check whether a record key is exists | ||
* @returns {Boolean} | ||
*/ | ||
ClientStorage.prototype.set = function (key, value, ttl) { | ||
if (this.LSSupport) { | ||
this.ls.setItem(key, this.__escape(value)); | ||
if (ttl) { | ||
this.ls.setItem(key + TTL_SUFFIX, +(new Date(Date.now() + (ttl * 1000)))); | ||
} | ||
} else if (this.cookies) { | ||
this.cookies.set(key, this.__escape(value), ttl); | ||
} else { | ||
this._data[key] = value; | ||
if (ttl) { | ||
this._data[key + TTL_SUFFIX] = +(new Date(Date.now() + (ttl * 1000))); | ||
} | ||
ClientStorage.prototype.has = function (key) { | ||
if (typeof key !== 'string') { | ||
return false; | ||
} | ||
return true; | ||
}; | ||
/* | ||
* @function | ||
* @memberOf ClientStorage | ||
* @name remove | ||
* @param {String} key - The name of the record to create/overwrite | ||
* @summary Remove a record. | ||
* @returns {Boolean} | ||
*/ | ||
ClientStorage.prototype.remove = function (key) { | ||
if (key && this.has(key)) { | ||
if (this.LSSupport) { | ||
this.ls.removeItem(key); | ||
this.ls.removeItem(key + TTL_SUFFIX); | ||
return true; | ||
} else if (this.cookies) { | ||
return this.cookies.remove(key); | ||
if (this.data.hasOwnProperty(key)) { | ||
if (this.ttlData[key] <= Date.now()) { | ||
this.remove(key); | ||
return false; | ||
} | ||
delete this._data[key]; | ||
delete this._data[key + TTL_SUFFIX]; | ||
return true; | ||
@@ -313,47 +110,14 @@ } | ||
/* | ||
* @function | ||
/** | ||
* @locus Client | ||
* @memberOf ClientStorage | ||
* @name has | ||
* @param {String} key - The name of the record to check | ||
* @summary Check if record exists | ||
* @returns {Boolean} | ||
*/ | ||
ClientStorage.prototype.has = function (key) { | ||
if (this.LSSupport) { | ||
return !!this.ls.getItem(key); | ||
} else if (this.cookies) { | ||
return this.cookies.has(key); | ||
} | ||
return this._data.hasOwnProperty(key); | ||
}; | ||
/* | ||
* @function | ||
* @memberOf ClientStorage | ||
* @name keys | ||
* @summary Returns all storage keys | ||
* @returns {[String]]} | ||
* @summary Returns an array of Strings with all readable keys. | ||
* @returns {[String]} | ||
*/ | ||
ClientStorage.prototype.keys = function () { | ||
if (this.LSSupport) { | ||
var i = this.ls.length; | ||
var results = []; | ||
var key; | ||
while (i--) { | ||
key = this.ls.key(i); | ||
if (key.indexOf(TTL_SUFFIX, key.length - TTL_SUFFIX_LENGTH) === -1) { | ||
results.push(this.ls.key(i)); | ||
} | ||
} | ||
return results; | ||
} else if (this.cookies) { | ||
return this.cookies.keys(); | ||
} | ||
return Object.keys(this._data).filter(function (_key) { | ||
return _key.indexOf(TTL_SUFFIX, _key.length - TTL_SUFFIX_LENGTH) === -1; | ||
}); | ||
return Object.keys(this.data); | ||
}; | ||
/* | ||
/** | ||
* @function | ||
@@ -366,68 +130,9 @@ * @memberOf ClientStorage | ||
ClientStorage.prototype.empty = function () { | ||
if (this.LSSupport && this.ls.length > 0) { | ||
var self = this; | ||
this.keys().forEach(function (key) { | ||
return self.remove(key); | ||
}); | ||
return true; | ||
} else if (this.cookies) { | ||
return this.cookies.remove(); | ||
} else if (Object.keys(this._data).length){ | ||
this._data = {}; | ||
return true; | ||
} | ||
return false; | ||
return this.remove(); | ||
}; | ||
/* | ||
* @function | ||
* @memberOf ClientStorage | ||
* @name __escape | ||
*/ | ||
ClientStorage.prototype.__escape = function (value) { | ||
try { | ||
return JSON.stringify(value); | ||
} catch (e) { | ||
try { | ||
return value.toString(); | ||
} catch (err) { | ||
return value; | ||
} | ||
} | ||
}; | ||
module.exports.JSStorage = JSStorage; | ||
module.exports.BrowserStorage = BrowserStorage; | ||
module.exports.CookiesStorage = CookiesStorage; | ||
/* | ||
* @function | ||
* @memberOf ClientStorage | ||
* @name __unescape | ||
*/ | ||
ClientStorage.prototype.__unescape = function (value) { | ||
try { | ||
return JSON.parse(value); | ||
} catch (e) { | ||
return value; | ||
} | ||
}; | ||
/* | ||
* @memberOf ClientStorage | ||
* @name LSSupport | ||
* @summary Test browser for localStorage support | ||
*/ | ||
ClientStorage.prototype.LSSupport = (function () { | ||
try { | ||
var support = 'localStorage' in window && window.localStorage !== null; | ||
if (support) { | ||
// Safari will throw an exception in Private mode | ||
window.localStorage.setItem('___test___', 'test'); | ||
window.localStorage.removeItem('___test___'); | ||
return true; | ||
} | ||
return false; | ||
} catch (e) { | ||
return false; | ||
} | ||
})(); | ||
module.exports.clientStorage = ClientStorage; | ||
module.exports.ClientStorage = new ClientStorage(); | ||
module.exports.ClientStorage = ClientStorage; |
{ | ||
"name": "ClientStorage", | ||
"version": "3.0.1", | ||
"version": "4.0.0", | ||
"description": "Bulletproof persistent browser storage, works with disabled Cookies and/or localStorage", | ||
@@ -17,2 +17,3 @@ "main": "./client-storage.js", | ||
"local storage", | ||
"cookie", | ||
"cookies", | ||
@@ -32,2 +33,3 @@ "disabled cookies", | ||
"local storage", | ||
"cookie", | ||
"cookies", | ||
@@ -34,0 +36,0 @@ "disabled cookies", |
130
README.md
@@ -1,7 +0,9 @@ | ||
# Persistent Client (Browser) Storage | ||
<a href="https://www.patreon.com/bePatron?u=20396046"> | ||
<img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160"> | ||
[![support](https://img.shields.io/badge/support-GitHub-white)](https://github.com/sponsors/dr-dimitru) | ||
[![support](https://img.shields.io/badge/support-PayPal-white)](https://paypal.me/veliovgroup) | ||
<a href="https://ostr.io/info/built-by-developers-for-developers"> | ||
<img src="https://ostr.io/apple-touch-icon-60x60.png" height="20"> | ||
</a> | ||
# Persistent Browser (Client) Storage | ||
- 👷 __100% Tests coverage__; | ||
@@ -38,4 +40,12 @@ - 📦 No external dependencies; | ||
var ClientStorage = require('ClientStorage').ClientStorage; | ||
var clientStorage = new ClientStorage(); | ||
``` | ||
### ES6 Import: | ||
```js | ||
import { ClientStorage } from 'ClientStorage'; | ||
const clientStorage = new ClientStorage(); | ||
``` | ||
### ES6 Import (Meteor): | ||
@@ -45,2 +55,3 @@ | ||
import { ClientStorage } from 'meteor/ostrio:cstorage'; | ||
const clientStorage = new ClientStorage(); | ||
``` | ||
@@ -50,35 +61,34 @@ | ||
- `ClientStorage.get('key')` - Read a record. If the key doesn't exist a *undefined* value will be returned; | ||
- `clientStorage.get('key')` - Read a record. If the key doesn't exist a *undefined* value will be returned; | ||
- `key` - {*String*} - Record's key; | ||
- `ClientStorage.set('key', value[, ttl])` - Create/overwrite a value in storage; | ||
- `clientStorage.set('key', value[, ttl])` - Create/overwrite a value in storage; | ||
- `key` - {*String*} - Record's key; | ||
- `value` - {*String*|[*mix*]|*Boolean*|*Object*} - Record's value (content); | ||
- `ttl` - {*Number*} — [Optional] Record's TTL in seconds; | ||
- `ClientStorage.remove('key')` - Remove a record; | ||
- `clientStorage.remove('key')` - Remove a record; | ||
- `key` - {*String*} - Record's key; | ||
- `ClientStorage.has('key')` - Check whether a record exists, returns a boolean value; | ||
- `clientStorage.has('key')` - Check whether a record exists, returns a boolean value; | ||
- `key` - {*String*} - Record's key; | ||
- `ClientStorage.keys()` - Returns an array of all storage keys; | ||
- `ClientStorage.empty()` - Empty storage (remove all key/value pairs). __Use with caution! (*May remove cookies which weren't set by you*)__. | ||
- `clientStorage.keys()` - Returns an array of all storage keys; | ||
- `clientStorage.empty()` - Empty storage (remove all key/value pairs). __Use with caution! (*May remove cookies which weren't set by you*)__. | ||
## Alternate usage: | ||
### Use `cookies` only: | ||
By default ClientStorage package handle selecting storage driver in the next order (descending priority): | ||
To use `cookies` as a driver for `ClientStorage` create new instance of `clientStorage` (*camel-case, first letter __lower-case__*): | ||
1. `localStorage` | ||
2. `cookies` | ||
3. `js` (*JS Object driven storage*) | ||
```js | ||
var clientStorage = require('ClientStorage').clientStorage; | ||
var csCookies = new clientStorage('cookies'); | ||
csCookies.has('locale'); // false | ||
csCookies.set('locale', 'en_US'); // true | ||
``` | ||
To alter priority pass "preferred driver" to `new ClientStorage(driverName)` constructor. | ||
or in ES6 (Meteor): | ||
### Use `cookies` only: | ||
Pass `cookies` as an argument to new instance of `ClientStorage`: | ||
```js | ||
import { clientStorage } from 'meteor/ostrio:cstorage'; | ||
const csLocalStorage = new clientStorage('cookies'); | ||
csLocalStorage.has('locale'); // false | ||
csLocalStorage.set('locale', 'en_US'); // true | ||
const { clientStorage } = require('ClientStorage'); | ||
var cookiesStorage = new ClientStorage('cookies'); | ||
cookiesStorage.has('locale'); // false | ||
cookiesStorage.set('locale', 'en_US'); // true | ||
``` | ||
@@ -88,18 +98,20 @@ | ||
To use `localStorage` as a driver for `ClientStorage` create new instance of `clientStorage` (*camel-case, first letter __lower-case__*): | ||
Pass `localStorage` as an argument to new instance of `ClientStorage`: | ||
```js | ||
var clientStorage = require('ClientStorage').clientStorage; | ||
var csLocalStorage = new clientStorage('localStorage'); | ||
csLocalStorage.has('locale'); // false | ||
csLocalStorage.set('locale', 'en_US'); // true | ||
const { clientStorage } = require('ClientStorage'); | ||
var locStorage = new ClientStorage('localStorage'); | ||
locStorage.has('locale'); // false | ||
locStorage.set('locale', 'en_US'); // true | ||
``` | ||
or in ES6 (Meteor): | ||
### Use `js` only: | ||
Pass `js` (*in-memory js object*) as an argument to new instance of `ClientStorage`: | ||
```js | ||
import { clientStorage } from 'meteor/ostrio:cstorage'; | ||
const csLocalStorage = new clientStorage('localStorage'); | ||
csLocalStorage.has('locale'); // false | ||
csLocalStorage.set('locale', 'en_US'); // true | ||
const { clientStorage } = require('ClientStorage'); | ||
var jsStorage = new ClientStorage('js'); | ||
jsStorage.has('locale'); // false | ||
jsStorage.set('locale', 'en_US'); // true | ||
``` | ||
@@ -111,12 +123,15 @@ | ||
Persistent `ReactiveVar` implementation: | ||
```js | ||
import { ReactiveVar } from 'meteor/reactive-var'; | ||
import { ReactiveVar } from 'meteor/reactive-var'; | ||
import { ClientStorage } from 'meteor/ostrio:cstorage'; | ||
const clientStorage = new ClientStorage(); | ||
const persistentReactive = (name, initial = false) => { | ||
const persistentReactive = (name, initial = undefined) => { | ||
let reactive; | ||
if (ClientStorage.has(name)) { | ||
reactive = new ReactiveVar(ClientStorage.get(name)); | ||
if (clientStorage.has(name)) { | ||
reactive = new ReactiveVar(clientStorage.get(name)); | ||
} else { | ||
ClientStorage.set(name, initial); | ||
clientStorage.set(name, initial); | ||
reactive = new ReactiveVar(initial); | ||
@@ -131,3 +146,3 @@ } | ||
reactive.curValue = newValue; | ||
ClientStorage.set(name, newValue); | ||
clientStorage.set(name, newValue); | ||
reactive.dep.changed(); | ||
@@ -139,5 +154,5 @@ }; | ||
const UILayout = persistentReactive('UILayout', 'two-columns'); | ||
UILayout.get(); // two-columns | ||
UILayout.set('single-column'); | ||
const layout = persistentReactive('ui-layout', 'two-columns'); | ||
layout.get(); // two-columns | ||
layout.set('single-column'); | ||
``` | ||
@@ -148,24 +163,24 @@ | ||
```js | ||
var ClientStorage = require('ClientStorage').ClientStorage; | ||
const clientStorage = new (require('ClientStorage').ClientStorage); | ||
ClientStorage.set('locale', 'en'); // true | ||
ClientStorage.set('country', 'usa'); // true | ||
ClientStorage.set('gender', 'male'); // true | ||
clientStorage.set('locale', 'en'); // true | ||
clientStorage.set('country', 'usa'); // true | ||
clientStorage.set('gender', 'male'); // true | ||
ClientStorage.get('gender'); // male | ||
clientStorage.get('gender'); // male | ||
ClientStorage.has('locale'); // true | ||
ClientStorage.has('city'); // false | ||
clientStorage.has('locale'); // true | ||
clientStorage.has('city'); // false | ||
ClientStorage.keys(); // ['locale', 'country', 'gender'] | ||
clientStorage.keys(); // ['locale', 'country', 'gender'] | ||
ClientStorage.remove('locale'); // true | ||
ClientStorage.get('locale'); // undefined | ||
clientStorage.remove('locale'); // true | ||
clientStorage.get('locale'); // undefined | ||
ClientStorage.keys(); // ['country', 'gender'] | ||
clientStorage.keys(); // ['country', 'gender'] | ||
ClientStorage.empty(); // true | ||
ClientStorage.keys(); // [] | ||
clientStorage.empty(); // true | ||
clientStorage.keys(); // [] | ||
ClientStorage.empty(); // false | ||
clientStorage.empty(); // false | ||
``` | ||
@@ -194,3 +209,4 @@ | ||
- [Become a patron](https://www.patreon.com/bePatron?u=20396046) — support my open source contributions with monthly donation | ||
- [Sponsor via GitHub](https://github.com/sponsors/dr-dimitru) | ||
- [Support via PayPal](https://paypal.me/veliovgroup) | ||
- Use [ostr.io](https://ostr.io) — [Monitoring](https://snmp-monitoring.com), [Analytics](https://ostr.io/info/web-analytics), [WebSec](https://domain-protection.info), [Web-CRON](https://web-cron.info) and [Pre-rendering](https://prerendering.com) for a website |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
29485
13
501
204
1