UNPKG

4.8 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _GenericError = require('../error/GenericError');
8
9var _GenericError2 = _interopRequireDefault(_GenericError);
10
11var _Storage = require('./Storage');
12
13var _Storage2 = _interopRequireDefault(_Storage);
14
15var _Window = require('../window/Window');
16
17var _Window2 = _interopRequireDefault(_Window);
18
19function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
21/**
22 * Implementation of the {@codelink Storage} interface that relies on the
23 * native {@code sessionStorage} DOM storage for storing its entries.
24 */
25class SessionStorage extends _Storage2.default {
26 static get $dependencies() {
27 return [_Window2.default];
28 }
29
30 /**
31 * Initializes the session storage.
32 * @param {Window} window
33 */
34 constructor(window) {
35 super();
36
37 /**
38 * The DOM storage providing the actual storage of the entries.
39 *
40 * @type {Storage}
41 */
42 this._storage = window.getWindow().sessionStorage;
43 }
44
45 /**
46 * @inheritdoc
47 */
48 init() {
49 return this;
50 }
51
52 /**
53 * @inheritdoc
54 */
55 has(key) {
56 return !!this._storage.getItem(key);
57 }
58
59 /**
60 * @inheritdoc
61 */
62 get(key) {
63 try {
64 return JSON.parse(this._storage.getItem(key)).value;
65 } catch (error) {
66 throw new _GenericError2.default('ima.storage.SessionStorage.get: Failed to parse a session ' + `storage item value identified by the key ${key}: ` + error.message);
67 }
68 }
69
70 /**
71 * @inheritdoc
72 */
73 set(key, value) {
74 try {
75 this._storage.setItem(key, JSON.stringify({
76 created: Date.now(),
77 value
78 }));
79 } catch (error) {
80 let storage = this._storage;
81 let isItemTooBig = storage.length === 0 || storage.length === 1 && storage.key(0) === key;
82
83 if (isItemTooBig) {
84 throw error;
85 }
86
87 this._deleteOldestEntry();
88 this.set(key, value);
89 }
90
91 return this;
92 }
93
94 /**
95 * @inheritdoc
96 */
97 delete(key) {
98 this._storage.removeItem(key);
99 return this;
100 }
101
102 /**
103 * @inheritdoc
104 */
105 clear() {
106 this._storage.clear();
107 return this;
108 }
109
110 /**
111 * @inheritdoc
112 */
113 keys() {
114 return new StorageIterator(this._storage);
115 }
116
117 /**
118 * @override
119 */
120 size() {
121 return this._storage.length;
122 }
123
124 /**
125 * Deletes the oldest entry in this storage.
126 */
127 _deleteOldestEntry() {
128 let oldestEntry = {
129 key: null,
130 created: Date.now() + 1
131 };
132
133 for (let key of this.keys()) {
134 let value = JSON.parse(this._storage.getItem(key));
135 if (value.created < oldestEntry.created) {
136 oldestEntry = {
137 key,
138 created: value.created
139 };
140 }
141 }
142
143 if (typeof oldestEntry.key === 'string') {
144 this.delete(oldestEntry.key);
145 }
146 }
147}
148
149exports.default = SessionStorage; /**
150 * Implementation of the iterator protocol and the iterable protocol for DOM
151 * storage keys.
152 *
153 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
154 */
155
156class StorageIterator {
157 /**
158 * Initializes the DOM storage iterator.
159 *
160 * @param {Storage} storage The DOM storage to iterate through.
161 */
162 constructor(storage) {
163 /**
164 * The DOM storage being iterated.
165 *
166 * @type {Storage}
167 */
168 this._storage = storage;
169
170 /**
171 * The current index of the DOM storage key this iterator will return
172 * next.
173 *
174 * @type {number}
175 */
176 this._currentKeyIndex = 0;
177 }
178
179 /**
180 * Iterates to the next item. This method implements the iterator protocol.
181 *
182 * @return {{done: boolean, value: (undefined|string)}} The next value in
183 * the sequence and whether the iterator is done iterating through
184 * the values.
185 */
186 next() {
187 if (this._currentKeyIndex >= this._storage.length) {
188 return {
189 done: true,
190 value: undefined
191 };
192 }
193
194 let key = this._storage.key(this._currentKeyIndex);
195 this._currentKeyIndex++;
196
197 return {
198 done: false,
199 value: key
200 };
201 }
202
203 /**
204 * Returns the iterator for this object (this iterator). This method
205 * implements the iterable protocol and provides compatibility with the
206 * {@code for..of} loops.
207 *
208 * @return {StorageIterator} This iterator.
209 */
210 [Symbol.iterator]() {
211 return this;
212 }
213}
214
215typeof $IMA !== 'undefined' && $IMA !== null && $IMA.Loader && $IMA.Loader.register('ima/storage/SessionStorage', [], function (_export, _context) {
216 'use strict';
217 return {
218 setters: [],
219 execute: function () {
220 _export('default', exports.default);
221 }
222 };
223});