@converse/skeletor 0.0.7 → 0.0.9

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.
Files changed (44) hide show
  1. package/README.md +38 -25
  2. package/dist/skeletor.js +10413 -6875
  3. package/dist/skeletor.js.map +1 -1
  4. package/dist/skeletor.min.js +74 -3
  5. package/dist/skeletor.min.js.map +1 -1
  6. package/package.json +23 -12
  7. package/src/collection.js +540 -395
  8. package/src/drivers/sessionStorage.js +226 -232
  9. package/src/element.js +132 -82
  10. package/src/eventemitter.js +187 -0
  11. package/src/helpers.js +148 -114
  12. package/src/{main.js → index.js} +21 -17
  13. package/src/listening.js +81 -0
  14. package/src/model.js +340 -240
  15. package/src/storage.js +223 -241
  16. package/src/types/collection.d.ts +366 -0
  17. package/src/types/collection.d.ts.map +1 -0
  18. package/src/types/drivers/sessionStorage.d.ts +37 -0
  19. package/src/types/drivers/sessionStorage.d.ts.map +1 -0
  20. package/src/types/element.d.ts +115 -0
  21. package/src/types/element.d.ts.map +1 -0
  22. package/src/types/eventemitter.d.ts +93 -0
  23. package/src/types/eventemitter.d.ts.map +1 -0
  24. package/src/types/helpers.d.ts +62 -0
  25. package/src/types/helpers.d.ts.map +1 -0
  26. package/src/types/index.d.ts +19 -0
  27. package/src/types/index.d.ts.map +1 -0
  28. package/src/types/listening.d.ts +40 -0
  29. package/src/types/listening.d.ts.map +1 -0
  30. package/src/types/model.d.ts +230 -0
  31. package/src/types/model.d.ts.map +1 -0
  32. package/src/types/storage.d.ts +35 -0
  33. package/src/types/storage.d.ts.map +1 -0
  34. package/src/types/utils/events.d.ts +28 -0
  35. package/src/types/utils/events.d.ts.map +1 -0
  36. package/src/utils/events.js +174 -0
  37. package/src/drivers/indexeddb-getitems.js~ +0 -1116
  38. package/src/drivers/indexeddb.js~ +0 -1115
  39. package/src/events.js +0 -328
  40. package/src/history.js +0 -301
  41. package/src/overview.js +0 -191
  42. package/src/router.js +0 -119
  43. package/src/storage.js~ +0 -269
  44. package/src/view.js +0 -267
@@ -1,13 +1,13 @@
1
1
  // Copyright 2014 Mozilla
2
2
  // Copyright 2015 Thodoris Greasidis
3
3
  // Copyright 2018 JC Brand
4
- //
4
+ //
5
5
  // Licensed under the Apache License, Version 2.0 (the "License");
6
6
  // you may not use this file except in compliance with the License.
7
7
  // You may obtain a copy of the License at
8
- //
8
+ //
9
9
  // http://www.apache.org/licenses/LICENSE-2.0
10
- //
10
+ //
11
11
  // Unless required by applicable law or agreed to in writing, software
12
12
  // distributed under the License is distributed on an "AS IS" BASIS,
13
13
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,297 +19,291 @@ import getCallback from 'localforage/src/utils/getCallback';
19
19
  import normalizeKey from 'localforage/src/utils/normalizeKey';
20
20
  import serializer from 'localforage/src/utils/serializer';
21
21
 
22
- const serialize = serializer["serialize"];
23
- const deserialize = serializer["deserialize"];
24
-
25
-
26
- function isSessionStorageValid () {
27
- // If the app is running inside a Google Chrome packaged webapp, or some
28
- // other context where sessionStorage isn't available, we don't use
29
- // sessionStorage. This feature detection is preferred over the old
30
- // `if (window.chrome && window.chrome.runtime)` code.
31
- // See: https://github.com/mozilla/localForage/issues/68
32
- try {
33
- // If sessionStorage isn't available, we get outta here!
34
- // This should be inside a try catch
35
- if (sessionStorage && ('setItem' in sessionStorage)) {
36
- return true;
37
- }
38
- } catch (e) {
39
- console.log(e);
22
+ const serialize = serializer['serialize'];
23
+ const deserialize = serializer['deserialize'];
24
+
25
+ function isSessionStorageValid() {
26
+ // If the app is running inside a Google Chrome packaged webapp, or some
27
+ // other context where sessionStorage isn't available, we don't use
28
+ // sessionStorage. This feature detection is preferred over the old
29
+ // `if (window.chrome && window.chrome.runtime)` code.
30
+ // See: https://github.com/mozilla/localForage/issues/68
31
+ try {
32
+ // If sessionStorage isn't available, we get outta here!
33
+ // This should be inside a try catch
34
+ if (sessionStorage && 'setItem' in sessionStorage) {
35
+ return true;
40
36
  }
41
- return false;
37
+ } catch (e) {
38
+ console.log(e);
39
+ }
40
+ return false;
42
41
  }
43
42
 
44
43
  function _getKeyPrefix(options, defaultConfig) {
45
- let keyPrefix = options.name + '/';
44
+ let keyPrefix = options.name + '/';
46
45
 
47
- if (options.storeName !== defaultConfig.storeName) {
48
- keyPrefix += options.storeName + '/';
49
- }
50
- return keyPrefix;
46
+ if (options.storeName !== defaultConfig.storeName) {
47
+ keyPrefix += options.storeName + '/';
48
+ }
49
+ return keyPrefix;
51
50
  }
52
51
 
53
52
  const dbInfo = {
54
- 'serializer': {
55
- 'serialize': serialize,
56
- 'deserialize': deserialize
57
- }
53
+ 'serializer': {
54
+ 'serialize': serialize,
55
+ 'deserialize': deserialize,
56
+ },
58
57
  };
59
58
 
60
59
  function _initStorage(options) {
61
- dbInfo.keyPrefix = _getKeyPrefix(options, this._defaultConfig);
62
- if (options) {
63
- for (const i in options) { // eslint-disable-line guard-for-in
64
- dbInfo[i] = options[i];
65
- }
60
+ dbInfo.keyPrefix = _getKeyPrefix(options, this._defaultConfig);
61
+ if (options) {
62
+ for (const i in options) {
63
+ // eslint-disable-line guard-for-in
64
+ dbInfo[i] = options[i];
66
65
  }
66
+ }
67
67
  }
68
68
 
69
69
  // Remove all keys from the datastore, effectively destroying all data in
70
70
  // the app's key/value store!
71
71
  function clear(callback) {
72
- const promise = this.ready().then(function() {
73
- const keyPrefix = dbInfo.keyPrefix;
72
+ const promise = this.ready().then(function () {
73
+ const keyPrefix = dbInfo.keyPrefix;
74
74
 
75
- for (let i = sessionStorage.length - 1; i >= 0; i--) {
76
- const key = sessionStorage.key(i);
75
+ for (let i = sessionStorage.length - 1; i >= 0; i--) {
76
+ const key = sessionStorage.key(i);
77
77
 
78
- if (key.indexOf(keyPrefix) === 0) {
79
- sessionStorage.removeItem(key);
80
- }
81
- }
82
- });
78
+ if (key.indexOf(keyPrefix) === 0) {
79
+ sessionStorage.removeItem(key);
80
+ }
81
+ }
82
+ });
83
83
 
84
- executeCallback(promise, callback);
85
- return promise;
84
+ executeCallback(promise, callback);
85
+ return promise;
86
86
  }
87
87
 
88
88
  // Retrieve an item from the store. Unlike the original async_storage
89
89
  // library in Gaia, we don't modify return values at all. If a key's value
90
90
  // is `undefined`, we pass that value to the callback function.
91
91
  function getItem(key, callback) {
92
- key = normalizeKey(key);
93
-
94
- const promise = this.ready().then(function() {
95
- let result = sessionStorage.getItem(dbInfo.keyPrefix + key);
96
- // If a result was found, parse it from the serialized
97
- // string into a JS object. If result isn't truthy, the key
98
- // is likely undefined and we'll pass it straight to the
99
- // callback.
100
- if (result) {
101
- result = dbInfo.serializer.deserialize(result);
102
- }
103
- return result;
104
- });
105
- executeCallback(promise, callback);
106
- return promise;
92
+ key = normalizeKey(key);
93
+
94
+ const promise = this.ready().then(function () {
95
+ let result = sessionStorage.getItem(dbInfo.keyPrefix + key);
96
+ // If a result was found, parse it from the serialized
97
+ // string into a JS object. If result isn't truthy, the key
98
+ // is likely undefined and we'll pass it straight to the
99
+ // callback.
100
+ if (result) {
101
+ result = dbInfo.serializer.deserialize(result);
102
+ }
103
+ return result;
104
+ });
105
+ executeCallback(promise, callback);
106
+ return promise;
107
107
  }
108
108
 
109
109
  // Iterate over all items in the store.
110
110
  function iterate(iterator, callback) {
111
- const self = this;
112
-
113
- const promise = self.ready().then(function() {
114
- const keyPrefix = dbInfo.keyPrefix;
115
- const keyPrefixLength = keyPrefix.length;
116
- const length = sessionStorage.length;
117
-
118
- // We use a dedicated iterator instead of the `i` variable below
119
- // so other keys we fetch in sessionStorage aren't counted in
120
- // the `iterationNumber` argument passed to the `iterate()`
121
- // callback.
122
- //
123
- // See: github.com/mozilla/localForage/pull/435#discussion_r38061530
124
- let iterationNumber = 1;
125
-
126
- for (let i = 0; i < length; i++) {
127
- const key = sessionStorage.key(i);
128
- if (key.indexOf(keyPrefix) !== 0) {
129
- continue;
130
- }
131
- let value = sessionStorage.getItem(key);
132
-
133
- // If a result was found, parse it from the serialized
134
- // string into a JS object. If result isn't truthy, the
135
- // key is likely undefined and we'll pass it straight
136
- // to the iterator.
137
- if (value) {
138
- value = dbInfo.serializer.deserialize(value);
139
- }
140
-
141
- value = iterator(
142
- value,
143
- key.substring(keyPrefixLength),
144
- iterationNumber++
145
- );
146
-
147
- if (value !== void 0) { // eslint-disable-line no-void
148
- return value;
149
- }
150
- }
151
- });
111
+ const self = this;
112
+
113
+ const promise = self.ready().then(function () {
114
+ const keyPrefix = dbInfo.keyPrefix;
115
+ const keyPrefixLength = keyPrefix.length;
116
+ const length = sessionStorage.length;
117
+
118
+ // We use a dedicated iterator instead of the `i` variable below
119
+ // so other keys we fetch in sessionStorage aren't counted in
120
+ // the `iterationNumber` argument passed to the `iterate()`
121
+ // callback.
122
+ //
123
+ // See: github.com/mozilla/localForage/pull/435#discussion_r38061530
124
+ let iterationNumber = 1;
125
+
126
+ for (let i = 0; i < length; i++) {
127
+ const key = sessionStorage.key(i);
128
+ if (key.indexOf(keyPrefix) !== 0) {
129
+ continue;
130
+ }
131
+ let value = sessionStorage.getItem(key);
132
+
133
+ // If a result was found, parse it from the serialized
134
+ // string into a JS object. If result isn't truthy, the
135
+ // key is likely undefined and we'll pass it straight
136
+ // to the iterator.
137
+ if (value) {
138
+ value = dbInfo.serializer.deserialize(value);
139
+ }
140
+
141
+ value = iterator(value, key.substring(keyPrefixLength), iterationNumber++);
142
+
143
+ if (value !== void 0) {
144
+ // eslint-disable-line no-void
145
+ return value;
146
+ }
147
+ }
148
+ });
152
149
 
153
- executeCallback(promise, callback);
154
- return promise;
150
+ executeCallback(promise, callback);
151
+ return promise;
155
152
  }
156
153
 
157
154
  // Same as sessionStorage's key() method, except takes a callback.
158
155
  function key(n, callback) {
159
- const self = this;
160
- const promise = self.ready().then(function() {
161
- let result;
162
- try {
163
- result = sessionStorage.key(n);
164
- } catch (error) {
165
- result = null;
166
- }
156
+ const self = this;
157
+ const promise = self.ready().then(function () {
158
+ let result;
159
+ try {
160
+ result = sessionStorage.key(n);
161
+ } catch (error) {
162
+ result = null;
163
+ }
167
164
 
168
- // Remove the prefix from the key, if a key is found.
169
- if (result) {
170
- result = result.substring(dbInfo.keyPrefix.length);
171
- }
165
+ // Remove the prefix from the key, if a key is found.
166
+ if (result) {
167
+ result = result.substring(dbInfo.keyPrefix.length);
168
+ }
172
169
 
173
- return result;
174
- });
170
+ return result;
171
+ });
175
172
 
176
- executeCallback(promise, callback);
177
- return promise;
173
+ executeCallback(promise, callback);
174
+ return promise;
178
175
  }
179
176
 
180
177
  function keys(callback) {
181
- const self = this;
182
- const promise = self.ready().then(function() {
183
- const length = sessionStorage.length;
184
- const keys = [];
185
-
186
- for (let i = 0; i < length; i++) {
187
- const itemKey = sessionStorage.key(i);
188
- if (itemKey.indexOf(dbInfo.keyPrefix) === 0) {
189
- keys.push(itemKey.substring(dbInfo.keyPrefix.length));
190
- }
191
- }
192
- return keys;
193
- });
178
+ const self = this;
179
+ const promise = self.ready().then(function () {
180
+ const length = sessionStorage.length;
181
+ const keys = [];
182
+
183
+ for (let i = 0; i < length; i++) {
184
+ const itemKey = sessionStorage.key(i);
185
+ if (itemKey.indexOf(dbInfo.keyPrefix) === 0) {
186
+ keys.push(itemKey.substring(dbInfo.keyPrefix.length));
187
+ }
188
+ }
189
+ return keys;
190
+ });
194
191
 
195
- executeCallback(promise, callback);
196
- return promise;
192
+ executeCallback(promise, callback);
193
+ return promise;
197
194
  }
198
195
 
199
196
  // Supply the number of keys in the datastore to the callback function.
200
197
  function length(callback) {
201
- const self = this;
202
- const promise = self.keys().then(function(keys) {
203
- return keys.length;
204
- });
198
+ const self = this;
199
+ const promise = self.keys().then(function (keys) {
200
+ return keys.length;
201
+ });
205
202
 
206
- executeCallback(promise, callback);
207
- return promise;
203
+ executeCallback(promise, callback);
204
+ return promise;
208
205
  }
209
206
 
210
207
  // Remove an item from the store, nice and simple.
211
208
  function removeItem(key, callback) {
212
- key = normalizeKey(key);
213
- const promise = this.ready().then(function() {
214
- sessionStorage.removeItem(dbInfo.keyPrefix + key);
215
- });
216
- executeCallback(promise, callback);
217
- return promise;
209
+ key = normalizeKey(key);
210
+ const promise = this.ready().then(function () {
211
+ sessionStorage.removeItem(dbInfo.keyPrefix + key);
212
+ });
213
+ executeCallback(promise, callback);
214
+ return promise;
218
215
  }
219
216
 
220
- // Set a key's value and run an optional callback once the value is set.
221
- // Unlike Gaia's implementation, the callback function is passed the value,
222
- // in case you want to operate on that value only after you're sure it
223
- // saved, or something like that.
224
- function setItem(key, value, callback) {
225
- key = normalizeKey(key);
226
-
227
- const promise = this.ready().then(function() {
228
- // Convert undefined values to null.
229
- // https://github.com/mozilla/localForage/pull/42
230
- if (value === undefined) {
231
- value = null;
217
+ /**
218
+ * Set a key's value and run an optional callback once the value is set.
219
+ * Unlike Gaia's implementation, the callback function is passed the value,
220
+ * in case you want to operate on that value only after you're sure it
221
+ * saved, or something like that.
222
+ * @template T
223
+ * @param {string} key - The key under which the value is stored.
224
+ * @param {T} value - The value to be stored, can be of any type.
225
+ * @param {(err: any, value: T) => void} [callback] - Optional callback function to be called after the value is set.
226
+ * @returns {Promise<T>}
227
+ */
228
+ async function setItem(key, value, callback) {
229
+ key = normalizeKey(key);
230
+ await this.ready();
231
+
232
+ // Convert undefined values to null.
233
+ // https://github.com/mozilla/localForage/pull/42
234
+ value = value ?? null;
235
+
236
+ // Save the original value to pass to the callback.
237
+ const originalValue = value;
238
+
239
+ dbInfo.serializer.serialize(value, (value, error) => {
240
+ if (error) {
241
+ throw error;
242
+ } else {
243
+ try {
244
+ sessionStorage.setItem(dbInfo.keyPrefix + key, value);
245
+ executeCallback(Promise.resolve(originalValue), callback);
246
+ } catch (e) {
247
+ if (e.name === 'QuotaExceededError' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED') {
248
+ console.error('Your sesionStorage capacity is used up.');
249
+ throw e;
232
250
  }
251
+ throw e;
252
+ }
253
+ }
254
+ });
233
255
 
234
- // Save the original value to pass to the callback.
235
- const originalValue = value;
236
-
237
- return new Promise(function(resolve, reject) {
238
- dbInfo.serializer.serialize(value, function(value, error) {
239
- if (error) {
240
- reject(error);
241
- } else {
242
- try {
243
- sessionStorage.setItem(dbInfo.keyPrefix + key, value);
244
- resolve(originalValue);
245
- } catch (e) {
246
- // sessionStorage capacity exceeded.
247
- // TODO: Make this a specific error/event.
248
- if (
249
- e.name === 'QuotaExceededError' ||
250
- e.name === 'NS_ERROR_DOM_QUOTA_REACHED'
251
- ) {
252
- reject(e);
253
- }
254
- reject(e);
255
- }
256
- }
257
- });
258
- });
259
- });
260
-
261
- executeCallback(promise, callback);
262
- return promise;
256
+ return value;
263
257
  }
264
258
 
265
259
  function dropInstance(options, callback) {
266
- callback = getCallback.apply(this, arguments);
267
-
268
- options = (typeof options !== 'function' && options) || {};
269
- if (!options.name) {
270
- const currentConfig = this.config();
271
- options.name = options.name || currentConfig.name;
272
- options.storeName = options.storeName || currentConfig.storeName;
273
- }
274
-
275
- const self = this;
276
- let promise;
277
- if (!options.name) {
278
- promise = Promise.reject(new Error('Invalid arguments'));
279
- } else {
280
- promise = new Promise(function(resolve) {
281
- if (!options.storeName) {
282
- resolve(`${options.name}/`);
283
- } else {
284
- resolve(_getKeyPrefix(options, self._defaultConfig));
285
- }
286
- }).then(function(keyPrefix) {
287
- for (let i = sessionStorage.length - 1; i >= 0; i--) {
288
- const key = sessionStorage.key(i);
289
- if (key.indexOf(keyPrefix) === 0) {
290
- sessionStorage.removeItem(key);
291
- }
292
- }
293
- });
294
- }
260
+ callback = getCallback.apply(this, arguments);
261
+
262
+ options = (typeof options !== 'function' && options) || {};
263
+ if (!options.name) {
264
+ const currentConfig = this.config();
265
+ options.name = options.name || currentConfig.name;
266
+ options.storeName = options.storeName || currentConfig.storeName;
267
+ }
268
+
269
+ const self = this;
270
+ let promise;
271
+ if (!options.name) {
272
+ promise = Promise.reject(new Error('Invalid arguments'));
273
+ } else {
274
+ promise = new Promise(function (resolve) {
275
+ if (!options.storeName) {
276
+ resolve(`${options.name}/`);
277
+ } else {
278
+ resolve(_getKeyPrefix(options, self._defaultConfig));
279
+ }
280
+ }).then(function (keyPrefix) {
281
+ for (let i = sessionStorage.length - 1; i >= 0; i--) {
282
+ const key = sessionStorage.key(i);
283
+ if (key.indexOf(keyPrefix) === 0) {
284
+ sessionStorage.removeItem(key);
285
+ }
286
+ }
287
+ });
288
+ }
295
289
 
296
- executeCallback(promise, callback);
297
- return promise;
290
+ executeCallback(promise, callback);
291
+ return promise;
298
292
  }
299
293
 
300
294
  const sessionStorageWrapper = {
301
- _driver: 'sessionStorageWrapper',
302
- _initStorage: _initStorage,
303
- _support: isSessionStorageValid(),
304
- iterate: iterate,
305
- getItem: getItem,
306
- setItem: setItem,
307
- removeItem: removeItem,
308
- clear: clear,
309
- length: length,
310
- key: key,
311
- keys: keys,
312
- dropInstance: dropInstance
295
+ _driver: 'sessionStorageWrapper',
296
+ _initStorage: _initStorage,
297
+ _support: isSessionStorageValid(),
298
+ iterate,
299
+ getItem,
300
+ setItem,
301
+ removeItem,
302
+ clear,
303
+ length,
304
+ key,
305
+ keys,
306
+ dropInstance,
313
307
  };
314
308
 
315
309
  export default sessionStorageWrapper;