@bizjournals/js-storage 0.0.1 → 0.1.1

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/.gitlab-ci.yml ADDED
@@ -0,0 +1,15 @@
1
+ npmrunner:
2
+ tags:
3
+ - php73
4
+ script:
5
+ - date
6
+ - node --version
7
+ - npm --version
8
+ - rm -f .npmrc
9
+ - mv build/.npmrc .npmrc
10
+ - npm install --loglevel=error
11
+ - npm test
12
+ - rm -rf node_modules
13
+ - rm -f .npmrc
14
+ except:
15
+ - tags
package/README.md CHANGED
@@ -0,0 +1,96 @@
1
+ # Storage
2
+ This bundle has helper classes to interact with browser storage options. At present we
3
+ support `localstorage` and `sessionstorage`. These share a common abstract parent.
4
+
5
+ Storage references are critical to the implementation of our architecture. A reference
6
+ is a named key that contains your data in the selected storage type.
7
+
8
+ ## Installing
9
+
10
+ Using npm:
11
+
12
+ ```bash
13
+ npm install @bizjournals/vue-core
14
+ ```
15
+
16
+ Using yarn:
17
+
18
+ ```bash
19
+ yarn add @bizjournals/vue-core
20
+ ```
21
+
22
+ **Configuring your environment:**
23
+
24
+ You will need to configure an `NPM_TOKEN` within your project to include these
25
+ private modules. The best idea is to use an existing project as an example.
26
+
27
+ _For simple setups the .gitlab-ci.yml file within this project as a guide to accessing
28
+ project variables via the .npmrc file_
29
+
30
+ ## Example
31
+
32
+ ```js
33
+ import { StorageReference, LocalStorage, SessionStorage } from "@bizjournals/js-storage";
34
+
35
+ // This will setup a reference that is namespaced to bizj
36
+ // The full key in localstorage will be bizj.mykey
37
+ // This key will have an expiration partner that by default will be one hour
38
+ const something = new StorageReference('mykey', new LocalStorage());
39
+
40
+ something.saveAs({
41
+ my: 'data'
42
+ });
43
+
44
+ // local storage has a configurable API as well, and this can be used in storage
45
+ // reference objects too.
46
+ const local = new LocalStorage({
47
+ // by changing the namespace what was bizj by default will now be notbizj
48
+ // Example: notbizj.mykey
49
+ namespace: 'notbizj',
50
+ expires: 3600 // one hour
51
+ });
52
+
53
+
54
+ // session storage uses the same api as local storage
55
+ const somethingElse = new StorageReference('difkey', new SessionStorage({
56
+ namespace: 'woa'
57
+ }));
58
+
59
+ const somethingElsesData = somethingElse.obtain();
60
+ ```
61
+
62
+ ## Storage Reference
63
+ A storage reference is a keyed object that exists within either local or session storage.
64
+ It may be prefixed with a namespace since of the respective storage container.
65
+
66
+ ### API
67
+
68
+ **constructor**(cacheKey : String, storageSystem : StorageAbstract)
69
+ **obtain**()
70
+ **bust**()
71
+ **saveAs**(data : Mixed)
72
+
73
+ ## Storage Abstract
74
+ The parent class for both local and session storage creates the API used by each of them.
75
+
76
+ ### API
77
+
78
+ **constructor**(options : Object : { namespace: String, expires: Number })
79
+ **getItem**(key: String)
80
+ **hasItem**(key : String)
81
+ **setItem**(key : String, value : Mixed, expires = true : Boolean)
82
+
83
+
84
+ ### Reference
85
+
86
+ #### getItem
87
+ Gets an item with a specified key. The namespace set in the construction of the object will
88
+ be pre-fixed to the beginning of the string, by default this is `bizj`.
89
+
90
+ #### hasItem
91
+ This checks to see if the item is available. If it is it'll cache it, so that if you need to
92
+ get the item later you don't need to worry about additional reads.
93
+
94
+ #### setItem
95
+ Sets the item in storage and updates the item in cache. It will automatically prefix itself
96
+ with the namespace, by default `bizj`.
@@ -0,0 +1,3 @@
1
+ module.exports = {
2
+ transformIgnorePatterns: ["/node_modules/(?!(@bizjournals))/"]
3
+ };
@@ -14,11 +14,6 @@ describe('core:class >> storageabstract:clear', () => {
14
14
  }).not.toThrow();
15
15
  });
16
16
 
17
- it('always returns `this`', () => {
18
- const test = storageAbstract.clear();
19
- expect(test).toEqual(storageAbstract);
20
- });
21
-
22
17
  it('runs the clear method on the storage system when defined', () => {
23
18
  storageAbstract.storage = {
24
19
  clear: jest.fn()
@@ -1,6 +1,5 @@
1
1
  import StorageAbstract from '../';
2
2
  import { DEFAULT_EXPIRATION, DEFAULT_NAMESPACE } from '../constants';
3
- import { NAMESPACE_MUST_BE_STRING, EXPIRATION_MUST_BE_POSITIVE_INTEGER } from '../exceptions';
4
3
 
5
4
  describe('core:class >> storageabstract:constructor', () => {
6
5
  it('defaults to constant as it\'s namespace when none provided', () => {
@@ -25,7 +24,7 @@ describe('core:class >> storageabstract:constructor', () => {
25
24
  for (const namespace of namespaces) {
26
25
  expect(() => {
27
26
  new StorageAbstract({ namespace });
28
- }).toThrow(NAMESPACE_MUST_BE_STRING);
27
+ }).toThrow();
29
28
  }
30
29
  });
31
30
 
@@ -40,11 +39,6 @@ describe('core:class >> storageabstract:constructor', () => {
40
39
  expect(storageAbstract.expires).toEqual(expires);
41
40
  });
42
41
 
43
- it('defaults the number of attempts to zero', () => {
44
- const storageAbstract = new StorageAbstract();
45
- expect(storageAbstract.attempts).toEqual(0);
46
- });
47
-
48
42
  it('sets the storage to a default of null', () => {
49
43
  const storageAbstract = new StorageAbstract();
50
44
  expect(storageAbstract.storage).toEqual({});
@@ -19,19 +19,20 @@ describe('core:class >> storageabstract:getitem', () => {
19
19
  };
20
20
 
21
21
  storageClassMock.storage = mockStorage;
22
+ StorageAbstract.supported = undefined;
22
23
  });
23
24
 
24
- it('returns null when it is not supported', () => {
25
+ it('returns undefined when it is not supported', () => {
25
26
  storageClassMock.isSupported = jest.fn().mockImplementation(() => false);
26
27
 
27
- expect(storageClassMock.getItem()).toEqual(null);
28
+ expect(storageClassMock.getItem()).toEqual(undefined);
28
29
  expect(storageClassMock.namespaceKey).not.toHaveBeenCalled();
29
30
  });
30
31
 
31
- it('returns null when the item is expired', () => {
32
+ it('returns undefined when the item is expired', () => {
32
33
  storageClassMock.isItemExpired = jest.fn().mockImplementation(() => true);
33
34
 
34
- expect(storageClassMock.getItem()).toEqual(null);
35
+ expect(storageClassMock.getItem()).toEqual(undefined);
35
36
  expect(storageClassMock.namespaceKey).not.toHaveBeenCalled();
36
37
  });
37
38
 
@@ -64,8 +65,16 @@ describe('core:class >> storageabstract:getitem', () => {
64
65
  expect(storageClassMock.parser).toHaveBeenCalledWith(data);
65
66
  });
66
67
 
67
- it('caches the response data once obtained', () => {
68
- storageClassMock.getItem(key);
69
- expect(storageClassMock.cache).toHaveBeenCalledTimes(1);
68
+ it('does not call the `parser` method with the data fetched from suspend or getItem', () => {
69
+ const data = { hey: 'you' };
70
+
71
+ const localStorage = {
72
+ getItem: jest.fn().mockImplementation(() => data)
73
+ };
74
+
75
+ storageClassMock.storage = localStorage;
76
+
77
+ storageClassMock.getItem(key, false);
78
+ expect(storageClassMock.parser).not.toHaveBeenCalled();
70
79
  });
71
80
  });
@@ -16,4 +16,10 @@ describe('core:class >> storageabstract:hasitem', () => {
16
16
 
17
17
  expect(storageClassMock.getItem).toHaveBeenCalledTimes(1);
18
18
  });
19
+
20
+ it('returns false when the obtained item is undefined', () => {
21
+ storageClassMock.getItem = jest.fn().mockImplementation(() => undefined);
22
+
23
+ expect(storageClassMock.hasItem(key)).toBeFalsy();
24
+ });
19
25
  });
@@ -1,5 +1,6 @@
1
1
  import StorageAbstract from '../';
2
2
  import mockStorage from '../__mocks__/mock-storage';
3
+ import store from '../store';
3
4
 
4
5
  describe('core:class >> storageabstract:issupported', () => {
5
6
  let storageAbstract;
@@ -9,10 +10,8 @@ describe('core:class >> storageabstract:issupported', () => {
9
10
  mockStorage.setItem.mockClear();
10
11
  mockStorage.removeItem.mockClear();
11
12
 
12
- if (mockStorage._supported) {
13
- delete mockStorage._supported;
14
- }
15
13
  storageAbstract.storage = mockStorage;
14
+ store.supported = undefined;
16
15
  });
17
16
 
18
17
  it('returns false when the storage system is defaulted', () => {
@@ -27,10 +27,14 @@ describe('core:class >> storageabstract:parser', () => {
27
27
  expect(JSON.parse).toHaveBeenCalledTimes(1);
28
28
  });
29
29
 
30
- it('throws an exception when string is not valid json', () => {
30
+ it('returns the provided string if it could not be JSON parsed', () => {
31
31
  JSON.parse = copyParse;
32
+ let response;
33
+
32
34
  expect(() => {
33
- storageAbstract.parser('wowowow');
34
- }).toThrow();
35
+ response = storageAbstract.parser('wowowow');
36
+ }).not.toThrow();
37
+
38
+ expect(response).toEqual('wowowow');
35
39
  });
36
40
  });
@@ -1,5 +1,7 @@
1
1
  import StorageAbstract from '../';
2
2
 
3
+ import store from '../store';
4
+
3
5
  describe('core:class >> storageabstract:removeitem', () => {
4
6
  let storageClassMock, mockStorage, key = 'test';
5
7
 
@@ -19,28 +21,22 @@ describe('core:class >> storageabstract:removeitem', () => {
19
21
  removeItem: jest.fn()
20
22
  };
21
23
 
22
- storageClassMock.attempts = 0;
23
24
  storageClassMock.storage = mockStorage;
25
+ store.supported = undefined;
24
26
  });
25
27
 
26
- it('resets the attempts and halts when it is not supported', () => {
28
+ it('halts when it is not supported', () => {
27
29
  storageClassMock.isSupported = jest.fn().mockImplementation(() => false);
28
- storageClassMock.removeItem(key);
29
-
30
- expect(storageClassMock.resetAttempts).toHaveBeenCalledTimes(1);
31
- expect(storageClassMock.storage.removeItem).not.toHaveBeenCalled();
32
- });
33
30
 
34
- it('resets the attempts and halts when attempts are >= 2', () => {
35
- storageClassMock.attempts = 2;
36
31
  storageClassMock.removeItem(key);
37
32
 
38
- expect(storageClassMock.resetAttempts).toHaveBeenCalledTimes(1);
33
+ expect(storageClassMock.isSupported).toHaveBeenCalledTimes(1);
39
34
  expect(storageClassMock.storage.removeItem).not.toHaveBeenCalled();
40
-
41
35
  });
42
36
 
43
- it('attempts two times when encountering an error', () => {
37
+ it('falls through when encountering an exception', () => {
38
+ store.supported = true;
39
+
44
40
  const badStorage = {
45
41
  removeItem: jest.fn().mockImplementation(() => {
46
42
  throw new Error('testing code');
@@ -48,23 +44,20 @@ describe('core:class >> storageabstract:removeitem', () => {
48
44
  };
49
45
 
50
46
  storageClassMock.storage = badStorage;
51
- storageClassMock.removeItem();
52
47
 
53
- expect(storageClassMock.storage.removeItem).toHaveBeenCalledTimes(2);
48
+ expect(() => {
49
+ storageClassMock.removeItem();
50
+ }).not.toThrow();
51
+
52
+ expect(storageClassMock.storage.removeItem).toHaveBeenCalledTimes(1);
54
53
  });
55
54
 
56
55
  it('removes both the item at namespace and expiration keys', () => {
56
+ store.supported = true;
57
57
  storageClassMock.removeItem();
58
58
 
59
59
  expect(storageClassMock.namespaceKey).toHaveBeenCalledTimes(1);
60
60
  expect(storageClassMock.expirationKey).toHaveBeenCalledTimes(1);
61
61
  expect(storageClassMock.storage.removeItem).toHaveBeenCalledTimes(2);
62
62
  });
63
-
64
- it('resets attempts to zero on successful return', () => {
65
- storageClassMock.removeItem();
66
-
67
- expect(storageClassMock.storage.removeItem).toHaveBeenCalledTimes(2);
68
- expect(storageClassMock.resetAttempts).toHaveBeenCalledTimes(1);
69
- });
70
63
  });
@@ -1,4 +1,5 @@
1
1
  import StorageAbstract from '../';
2
+ import store from '../store';
2
3
 
3
4
  describe('core:class >> storageabstract:setitem', () => {
4
5
  let storageClassMock, mockStorage, key = 'test';
@@ -26,22 +27,16 @@ describe('core:class >> storageabstract:setitem', () => {
26
27
 
27
28
  storageClassMock.attempts = 0;
28
29
  storageClassMock.storage = mockStorage;
30
+ store.supported = undefined;
29
31
  });
30
32
 
31
33
  it('resets the attempts and returns when it is not supported without continuing', () => {
32
34
  storageClassMock.isSupported = jest.fn().mockImplementation(() => false);
33
35
  storageClassMock.setItem();
34
36
 
35
- expect(storageClassMock.resetAttempts).toHaveBeenCalledTimes(1);
36
- expect(storageClassMock.namespaceKey).not.toHaveBeenCalled();
37
- });
38
-
39
- it('resets the attempts and returns when attempts is >= 2 without continuing', () => {
40
- storageClassMock.attempts = 3;
41
- storageClassMock.setItem();
42
-
43
- expect(storageClassMock.resetAttempts).toHaveBeenCalledTimes(1);
37
+ expect(storageClassMock.isSupported).toHaveBeenCalledTimes(1);
44
38
  expect(storageClassMock.namespaceKey).not.toHaveBeenCalled();
39
+ expect(mockStorage.setItem).not.toHaveBeenCalled();
45
40
  });
46
41
 
47
42
  it('uses a dynamically generated namespaceKey to set the item', () => {
@@ -59,7 +54,7 @@ describe('core:class >> storageabstract:setitem', () => {
59
54
  expect(storageClassMock.storage.setItem).not.toHaveBeenCalled();
60
55
  });
61
56
 
62
- it('calls to set the item one time when not expired', () => {
57
+ it('calls to set the item one time when not expiring', () => {
63
58
  const data = { it: true };
64
59
 
65
60
  storageClassMock.setItem(key, data, false);
@@ -77,25 +72,4 @@ describe('core:class >> storageabstract:setitem', () => {
77
72
  expect(storageClassMock.storage.setItem).toHaveBeenCalledTimes(2);
78
73
  expect(storageClassMock.expirationKey).toHaveBeenCalledTimes(1);
79
74
  });
80
-
81
- it('calls to cache the data with the key', () => {
82
- const data = { it: true };
83
-
84
- storageClassMock.setItem(key, data);
85
- expect(storageClassMock.cache).toHaveBeenCalledTimes(1);
86
- });
87
-
88
- it('calls clear when there is an error and attempts up to 2 times', () => {
89
- storageClassMock.translator = jest.fn().mockImplementation(() => {
90
- throw new Error('testing script error');
91
- });
92
-
93
- storageClassMock.setItem(key, { data: true });
94
- expect(storageClassMock.translator).toHaveBeenCalledTimes(2);
95
- });
96
-
97
- it('calls to reset attempts to zero once completed', () => {
98
- storageClassMock.setItem(key, { data: true });
99
- expect(storageClassMock.resetAttempts).toHaveBeenCalledTimes(1);
100
- });
101
75
  });
@@ -1,6 +1,5 @@
1
1
  import StorageAbstract from '../';
2
2
 
3
- // Mocking JSON.parse failed in this version of Jest
4
3
  describe('core:class >> storageabstract:translator', () => {
5
4
  let storageAbstract;
6
5
 
@@ -1,11 +1,6 @@
1
- import { empty } from "@bizjournals/js-utilities";
2
1
  import { DEFAULT_EXPIRATION, DEFAULT_NAMESPACE, EXPIRES_KEY_SUFFIX } from "./constants";
3
2
  import { KEY_IS_REQUIRED_TO_FETCH_DATA } from "./exceptions";
4
-
5
- // module scoped caching object
6
- // does share data between session / local / any other
7
- // If this becomes necessary attach it to the storage object
8
- const cache = {};
3
+ import store from './store';
9
4
 
10
5
  /*
11
6
  |--------------------------------------------------------------------------
@@ -25,41 +20,36 @@ export default class StorageAbstract {
25
20
  * @param {object} options
26
21
  * @constructor
27
22
  */
28
- constructor(options = {}) {
23
+ constructor (options = {}) {
29
24
  this.namespace = options.namespace || DEFAULT_NAMESPACE;
30
25
  this.expires = options.expires || DEFAULT_EXPIRATION;
31
- this.attempts = 0;
32
26
 
33
27
  this.namespace = this.namespace.toLowerCase();
34
28
 
35
- cache[this.namespace] = cache[this.namespace] || {};
36
-
37
29
  this.storage = {};
38
30
  }
39
31
 
40
32
  /**
41
- * Gets an item from storage.
33
+ * Gets an item from storage and runs the parser unless explicitly
34
+ * disabled in the method request.
42
35
  *
43
- * @param {string} key
44
- * @returns {(Array|Number|Object|String)}
36
+ * @param {String} key
37
+ * @param {Boolean} parse
38
+ * @returns {(Array|Number|Object|String|Null)}
45
39
  */
46
- getItem(key) {
47
- if (!this.isSupported() || this.isItemExpired(key)) {
48
- return null;
49
- }
50
-
51
- let response = null;
40
+ getItem (key, parse = true) {
41
+ let response;
52
42
 
53
- if (cache[this.namespace][key]) {
54
- return cache[this.namespace][key];
43
+ if (!this.isSupported() || this.isItemExpired(key)) {
44
+ return response;
55
45
  }
56
46
 
57
47
  try {
58
- const generatedKey = this.namespaceKey(key);
48
+ response = this.storage.getItem(this.namespaceKey(key));
59
49
 
60
- response = this.parser(cache[generatedKey] || this.storage.getItem(generatedKey));
50
+ if (response === null) return undefined;
61
51
 
62
- this.cache(key, response);
52
+ response = parse ? this.parser(response) : response;
63
53
  } catch (e) {
64
54
  // fall through
65
55
  }
@@ -71,10 +61,18 @@ export default class StorageAbstract {
71
61
  * Parses the data returned from the storage system
72
62
  *
73
63
  * @param data
74
- * @returns {any}
64
+ * @returns {*}
75
65
  */
76
- parser(data) {
77
- return typeof data === "string" ? JSON.parse(data) : data;
66
+ parser (data) {
67
+ try {
68
+ if (typeof data === "string") {
69
+ data = JSON.parse(data);
70
+ }
71
+ } catch (e) {
72
+ // fall through
73
+ }
74
+
75
+ return data;
78
76
  }
79
77
 
80
78
  /**
@@ -83,8 +81,8 @@ export default class StorageAbstract {
83
81
  * @param value
84
82
  * @returns {any}
85
83
  */
86
- translator(value) {
87
- return typeof value === "string" ? value : JSON.stringify(value);
84
+ translator (value) {
85
+ return typeof value === 'string' ? value : JSON.stringify(value);
88
86
  }
89
87
 
90
88
  /**
@@ -94,9 +92,9 @@ export default class StorageAbstract {
94
92
  * @param {(array|object|number|string)} value
95
93
  * @param {boolean} expires
96
94
  */
97
- setItem(key, value, expires = true) {
98
- if (!this.isSupported() || this.attempts >= 2) {
99
- return this.resetAttempts();
95
+ setItem (key, value, expires = true) {
96
+ if (!this.isSupported()) {
97
+ return;
100
98
  }
101
99
 
102
100
  const generatedKey = this.namespaceKey(key);
@@ -105,16 +103,14 @@ export default class StorageAbstract {
105
103
  this.storage.setItem(generatedKey, this.translator(value));
106
104
 
107
105
  if (expires) {
108
- this.storage.setItem(this.expirationKey(key), String(this.timestamp(this.expires)));
106
+ this.storage.setItem(
107
+ this.expirationKey(key),
108
+ String(this.timestamp(this.expires))
109
+ );
109
110
  }
110
-
111
- this.cache(key, value);
112
111
  } catch (e) {
113
- this.attempts++;
114
- this.setItem(key, value, expires);
112
+ // fall through
115
113
  }
116
-
117
- return this.resetAttempts();
118
114
  }
119
115
 
120
116
  /**
@@ -122,48 +118,28 @@ export default class StorageAbstract {
122
118
  *
123
119
  * @param {string} key
124
120
  */
125
- removeItem(key) {
126
- if (!this.isSupported() || this.attempts >= 2) {
127
- return this.resetAttempts();
121
+ removeItem (key) {
122
+ if (!this.isSupported()) {
123
+ return;
128
124
  }
129
125
 
130
126
  try {
131
127
  this.storage.removeItem(this.namespaceKey(key));
132
128
  this.storage.removeItem(this.expirationKey(key));
133
-
134
- this.free(key);
135
129
  } catch (e) {
136
- this.attempts++;
137
- this.removeItem(key);
130
+ // fall through
138
131
  }
139
-
140
- return this.resetAttempts();
141
- }
142
-
143
- /**
144
- * Resets the number of attempt operations to zero.
145
- *
146
- * @returns {StorageAbstract}
147
- */
148
- resetAttempts() {
149
- this.attempts = 0;
150
-
151
- return this;
152
132
  }
153
133
 
154
134
  /**
155
135
  * Clears all items from storage.
156
136
  */
157
- clear() {
137
+ clear () {
158
138
  try {
159
139
  this.storage.clear();
160
-
161
- cache[this.namespace] = {};
162
140
  } catch (e) {
163
141
  // fall through
164
142
  }
165
-
166
- return this;
167
143
  }
168
144
 
169
145
  /**
@@ -172,8 +148,8 @@ export default class StorageAbstract {
172
148
  * @param {string} key
173
149
  * @returns {boolean}
174
150
  */
175
- hasItem(key) {
176
- return !empty(this.getItem(key));
151
+ hasItem (key) {
152
+ return this.getItem(key, false) !== undefined;
177
153
  }
178
154
 
179
155
  /**
@@ -182,7 +158,7 @@ export default class StorageAbstract {
182
158
  * @param {number} offset
183
159
  * @returns {number}
184
160
  */
185
- timestamp(offset = 0) {
161
+ timestamp (offset = 0) {
186
162
  return Math.ceil(Date.now() / 1000) + offset;
187
163
  }
188
164
 
@@ -192,16 +168,16 @@ export default class StorageAbstract {
192
168
  * @param {string} key
193
169
  * @returns {string}
194
170
  */
195
- namespaceKey(key) {
171
+ namespaceKey (key) {
196
172
  if (typeof key !== "string") {
197
173
  throw new Error(KEY_IS_REQUIRED_TO_FETCH_DATA);
198
174
  }
199
175
 
200
- if (key.indexOf(`${this.namespace}.`) === 0) {
176
+ if (key.indexOf(`${ this.namespace }.`) === 0) {
201
177
  key = key.slice(this.namespace.length + 1);
202
178
  }
203
179
 
204
- return `${this.namespace}.${key.toLowerCase()}`;
180
+ return `${ this.namespace }.${ key.toLowerCase() }`;
205
181
  }
206
182
 
207
183
  /**
@@ -209,8 +185,8 @@ export default class StorageAbstract {
209
185
  *
210
186
  * @returns {string}
211
187
  */
212
- expirationKey(key) {
213
- return `${this.namespaceKey(key)}.${EXPIRES_KEY_SUFFIX}`;
188
+ expirationKey (key) {
189
+ return `${ this.namespaceKey(key) }.${ EXPIRES_KEY_SUFFIX }`;
214
190
  }
215
191
 
216
192
  /**
@@ -219,7 +195,7 @@ export default class StorageAbstract {
219
195
  * @param {string} key
220
196
  * @returns {boolean}
221
197
  */
222
- isItemExpired(key) {
198
+ isItemExpired (key) {
223
199
  if (!this.isSupported()) {
224
200
  return false;
225
201
  }
@@ -242,52 +218,38 @@ export default class StorageAbstract {
242
218
  return false;
243
219
  }
244
220
 
245
- /**
246
- * Stores the data in memory.
247
- *
248
- * @param key
249
- * @param value
250
- */
251
- cache(key, value) {
252
- cache[this.namespace][key] = value;
253
-
254
- return this;
255
- }
256
-
257
- /**
258
- * Frees the data from memory.
259
- *
260
- * @param key
261
- * @param value
262
- */
263
- free(key) {
264
- if (cache[this.namespace][key]) {
265
- delete cache[this.namespace][key];
266
- }
267
-
268
- return this;
269
- }
270
-
271
221
  /**
272
222
  * Checks to see if the storage system is supported
273
223
  *
274
224
  * @returns {boolean}
275
225
  */
276
- isSupported() {
277
- if (typeof this.storage._supported === "boolean") {
278
- return this.storage._supported;
226
+ isSupported () {
227
+ if (typeof store.supported === "boolean") {
228
+ return store.supported;
279
229
  }
280
230
 
281
- const test = `${this.namespaceKey("storage")}.test`;
231
+ const test = 'biz.storage.test';
282
232
 
283
233
  try {
284
- this.storage.setItem(test, test);
234
+ this.storage.setItem(test, '1');
285
235
  this.storage.removeItem(test);
286
- this.storage._supported = true;
236
+
237
+ store.supported = true;
287
238
  } catch (e) {
288
- this.storage._supported = false;
239
+ store.supported = e instanceof DOMException &&
240
+ (
241
+ // everything except Firefox
242
+ e.code === 22 ||
243
+ // Firefox
244
+ e.code === 1014 ||
245
+ // test name field too, because code might not be present
246
+ // everything except Firefox
247
+ e.name === 'QuotaExceededError' ||
248
+ // Firefox
249
+ e.name === 'NS_ERROR_DOM_QUOTA_REACHED'
250
+ ) && (this.storage && this.storage.length !== 0);
289
251
  }
290
252
 
291
- return this.storage._supported;
253
+ return store.supported;
292
254
  }
293
255
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * The data store for global variables
3
+ *
4
+ */
5
+ const store = {
6
+ supported: null,
7
+ }
8
+
9
+ // --
10
+ export default store;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bizjournals/js-storage",
3
- "version": "0.0.1",
3
+ "version": "0.1.1",
4
4
  "description": "ACBJ javascript storage classes",
5
5
  "repository": {
6
6
  "git": "https://gitlab.bizjournals.com/bizjournals/js-storage"
@@ -9,17 +9,17 @@
9
9
  "type": "module",
10
10
  "sideEffects": false,
11
11
  "scripts": {
12
- "test": "jest --transformIgnorePatterns \"node_modules/(?!(@bizjournals))/\""
12
+ "test": "jest",
13
+ "preversion": "npm test",
14
+ "postversion": "git push && git push --tags && npm publish"
13
15
  },
14
16
  "keywords": [],
15
17
  "author": "DPD",
16
18
  "license": "UNLICENSED",
17
19
  "devDependencies": {
18
- "@babel/preset-env": "^7.9.5",
20
+ "@babel/preset-env": "^7.10.3",
19
21
  "babel-jest": "^25.4.0",
20
22
  "jest": "^25.4.0"
21
23
  },
22
- "dependencies": {
23
- "@bizjournals/js-utilities": "0.0.1"
24
- }
24
+ "dependencies": {}
25
25
  }
@@ -1,20 +0,0 @@
1
- import StorageAbstract from '../';
2
-
3
- describe('core:class >> storageabstract:resetattempts', () => {
4
- let storageAbstract;
5
-
6
- beforeAll(() => {
7
- storageAbstract = new StorageAbstract();
8
- });
9
-
10
- it('resets the attempts to 0 when called', () => {
11
- storageAbstract.attempts = 2;
12
-
13
- storageAbstract.resetAttempts();
14
- expect(storageAbstract.attempts).toEqual(0);
15
- });
16
-
17
- it('returns `this`', () => {
18
- expect(storageAbstract.resetAttempts()).toEqual(storageAbstract);
19
- });
20
- });
File without changes