d8ecc205275359b599fffd9b1337a8488e9148fa4506dd88a0d9090c9092c8a79a3ab19c435a85a7d310332048300516be6e1b306879b7fd787e64acc4eb90 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. A feature-filled and friendly way to take advantage of localStorage and sessionStorage
  2. (JSON, namespacing, extensions, etc).
  3. Download: [store2.min.js][prod] or [store2.js][dev]
  4. [NPM][npm]: `npm install store2`
  5. [NuGet][]: `Install-Package store2`
  6. [NuGet]: http://nuget.org/packages/store2/
  7. [prod]: https://raw.github.com/nbubna/store/master/dist/store2.min.js
  8. [dev]: https://raw.github.com/nbubna/store/master/dist/store2.js
  9. [npm]: https://npmjs.org/package/store2
  10. [![Build Status](https://travis-ci.org/nbubna/store.svg?branch=master)](https://travis-ci.org/nbubna/store)
  11. [![npm version](https://badge.fury.io/js/store2.svg)](https://badge.fury.io/js/store2)
  12. [![npm](https://img.shields.io/npm/dm/store2.svg?maxAge=2592000)](https://www.npmjs.com/package/store2)
  13. ## Documentation
  14. The main store function can handle ```set```, ```get```, ```transact```, ```setAll```, ```getAll```, ```each```, and ```clear```
  15. actions directly. Respectively, these are called like so:
  16. ```javascript
  17. store(key, data); // sets stringified data under key
  18. store(key); // gets and parses data stored under key
  19. store(key, fn[, alt]); // run transaction function on/with data stored under key
  20. store({key: data, key2: data2}); // sets all key/data pairs in the object
  21. store(); // gets all stored key/data pairs as an object
  22. store((key, data)=>{ }); // calls function for each key/data in storage, return false to exit
  23. store(false); // clears all items from storage
  24. ```
  25. Parameters in [brackets] are optional. There are also more explicit and versatile functions available:
  26. ```javascript
  27. store.set(key, data[, overwrite]); // === store(key, data);
  28. store.setAll(data[, overwrite]); // === store({key: data, key2: data});
  29. store.get(key[, alt]); // === store(key);
  30. store.getAll([fillObj]); // === store();
  31. store.transact(key, fn[, alt]); // === store(key, fn[, alt]);
  32. store.clear(); // === store(false);
  33. store.has(key); // returns true or false
  34. store.remove(key[, alt]); // removes key and its data, then returns the data or alt, if none
  35. store.each(fn[, fill]); // === store(fn); optional call arg will be 3rd fn arg (e.g. for gathering values)
  36. store.add(key, data[, replacer]); // concats, merges, or adds new value into existing one
  37. store.keys([fillList]); // returns array of keys
  38. store.size(); // number of keys, not length of data
  39. store.clearAll(); // clears *ALL* areas (but still namespace sensitive)
  40. ```
  41. Passing in ```false``` for the optional overwrite parameters will cause ```set``` actions to be skipped
  42. if the storage already has a value for that key. All ```set``` action methods return the previous value
  43. for that key, by default. If overwrite is ```false``` and there is a previous value, the unused new
  44. value will be returned.
  45. Functions passed to ```transact``` will receive the current value for that key as an argument or
  46. a passed alternate if there is none. When the passed function is completed, transact will save the returned value
  47. under the specified key. If the function returns ```undefined```, the original value will be saved.
  48. This makes it easy for transact functions to change internal properties in a persistent way:
  49. ```javascript
  50. store.transact(key, function(obj) {
  51. obj.changed = 'newValue';// this change will be persisted
  52. });
  53. ```
  54. Functions passed to ```each``` will receive the key as first argument and current value as the second; if a `fill` parameter is specified, it's value will be the third argument for every call (few should ever
  55. need a `fill` parameter). If the function returns ```false``` at any point during the iteration, the
  56. loop will exit early and not continue on to the next key/value pair.
  57. ```javascript
  58. store.each(function(key, value) {
  59. console.log(key, '->', value);
  60. if (key === 'stopLoop') {
  61. return false;// this will cause each to stop calling this function
  62. }
  63. });
  64. ```
  65. All retrieval functions which take an optional ```alt``` parameter can also use that parameter to specify a "reviver" function. These receive each key and value (yes, nested ones too) as arguments and allow you to provide an alternate means of parsing that string. This is particularly useful for rich objects like ```Date``` types. See [MDN's JSON.parse docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) for more information and examples. Alternately, you can set a global reviver to the ```store._.revive``` property to handle all ```get```, ```getAll```, ```remove```, and ```transact``` calls.
  66. Likewise, setter functions which take an optional ```overwrite``` parameter can also use that parameter to accept a "replacer" function that receives each key and value (yes, nested ones too) as arguments and allow you to provide an alternate means of stringifying the values. This is particularly useful for rich objects like ```Map``` or ```Set```. See [MDN's JSON.stringify docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) for more information and examples. Alternately, you can set a global replacer to the ```store._.replace``` property to handle all ```set```, ```setAll```, ```add```, and ```transact``` calls.
  67. For ```getAll``` and ```keys```, there is the option to pass in the object or list, respectively,
  68. that you want the results to be added to. This is instead of an empty list.
  69. There are only a few special cases where you are likely to need or want this,
  70. in general, most users should ignore these optional parameters.
  71. These both use the second, optional argument ```each``` function,
  72. which is also a niche feature. The ```value``` argument is passed as
  73. the second arg to the callback function (in place of the data associated with the current key)
  74. and is returned at the end. Again, most users should not need this feature.
  75. All of these use the browser's localStorage (aka "local"). Using sessionStorage merely requires
  76. calling the same functions on ```store.session```:
  77. ```javascript
  78. store.session("addMeTo", "sessionStorage");
  79. store.local({lots: 'of', data: 'altogether'});// store.local === store :)
  80. ```
  81. There is also a store API automatically available for keeping non-persistent information,
  82. meant only to last until page reload.
  83. ```javascript
  84. store.page("until","reload");
  85. ```
  86. All the specific ```get```, ```set```, etc. functions are available on ```store.session```, ```store.local```, and ```store.page```, as well as any other storage facility registered via ```store.area(name, customStorageObject)``` by an extension, where customStorageObject must implement the [Storage interface][storage]. This is how [store.old.js][old] extends store.js to support older versions of IE and Firefox.
  87. [storage]: http://dev.w3.org/html5/webstorage/#the-storage-interface
  88. If you want to put stored data from different pages or areas f your site into separate namespaces,
  89. the ```store.namespace(ns)``` function is your friend:
  90. ```javascript
  91. var cart = store.namespace('cart');
  92. cart('total', 23.25);// stores in localStorage as 'cart.total'
  93. console.log(store('cart.total') == cart('total'));// logs true
  94. console.log(store.cart.getAll());// logs {total: 23.25}
  95. cart.session('group', 'toys');// stores in sessionStorage as 'cart.group'
  96. ```
  97. The namespace provides the same exact API as ```store``` but silently adds/removes the namespace prefix as needed.
  98. It also makes the namespaced API accessible directly via ```store[namespace]``` (e.g. ```store.cart```) as long as it
  99. does not conflict with an existing part of the store API.
  100. The 'namespace' function is one of three "extra" functions that are also part of the "store API":
  101. ```javascript
  102. store.namespace(prefix);// returns a new store API that prefixes all key-based functions
  103. store.isFake([force]);// test or set whether localStorage/sessionStorage or an in-memory, 'fake' storage is used
  104. ```
  105. ```store.namespace``` can also take extra params to only create the namespace in the called-on storage area, and
  106. to pass in an alternate namespace delimiter for advanced use-cases (e.g. ```store.page.namespace("subpage", true, ":")```).
  107. If localStorage or sessionStorage are unavailable, they will be faked to prevent errors,
  108. but data stored will NOT persist beyond the life of the current document/page. Use the
  109. [store.old.js][old] extension to add persistent backing for the store API in ancient browsers.
  110. ```isFake(true|false)``` is particularly useful to force use of a temporary, fake storage in testing situations,
  111. to prevent cluttering actual storage.
  112. ## Extensions
  113. These mostly could use further documentation and abuse...er...testing.
  114. Contributions are welcome!
  115. In particular, any ES6 user interested in making these [importable in ES6][es6importissue] would be appreciated.
  116. [es6importissue]: https://github.com/nbubna/store/issues/31
  117. #### Beta - Stable and definitely useful
  118. * [store.old.js][old] - Add working localStorage and sessionStorage polyfills for ancient browsers
  119. * [store.overflow.js][overflow] - Fall back to fake storage on quota errors
  120. * [store.cache.js][cache] - To make data expire, pass a number of seconds as the overwrite (third) param on ```set()``` calls
  121. * [store.on.js][on] - Superior storage event handling (per key, per namespace, etc in IE9+)
  122. * [store.array.js][array] - Easy, powerful array functions for any and all data (e.g. ```store.push(key, v1, v2)```).
  123. * [store.dom.js][dom] - Declarative, persistent DOM element content via store.
  124. * [store.cookie.js][cookie] - Support for a cookie as a storage area: ```store.cookie('num',1)``` to make sharing with backend easier.
  125. #### Alpha - Either incomplete or unstable or both
  126. * [store.quota.js][quota] - Register callbacks to handle (and even cancel) quota errors
  127. * [store.measure.js][measure] - Experimental extension for measuring space used and available (needs work)
  128. * [store.onlyreal.js][onlyreal] - When only fake storage is available, silently fail instead of faking it.
  129. * [store.dot.js][dot] - Creates accessors for keys (e.g. ```store.foo == store.get('foo')```)
  130. * [store.deep.js][deep] - Allow retrieval of properties from within stored objects (e.g. ```store.get('key.property')```)
  131. * [store.async.js][async] - Adds ```store.async``` duplicate to each store and namespace that performs functions asynchronously and returns a Promise that resolves when complete.
  132. * [store.cookies.js][cookies] - Support managing all cookies as a storage area with the store API (e.g. ```store.cookies.get('user')```)
  133. [old]: https://raw.github.com/nbubna/store/master/src/store.old.js
  134. [overflow]: https://raw.github.com/nbubna/store/master/src/store.overflow.js
  135. [cache]: https://raw.github.com/nbubna/store/master/src/store.cache.js
  136. [on]: https://raw.github.com/nbubna/store/master/src/store.on.js
  137. [quota]: https://raw.github.com/nbubna/store/master/src/store.quota.js
  138. [measure]: https://raw.github.com/nbubna/store/master/src/store.measure.js
  139. [onlyreal]: https://raw.github.com/nbubna/store/master/src/store.onlyreal.js
  140. [array]: https://raw.github.com/nbubna/store/master/src/store.array.js
  141. [dot]: https://raw.github.com/nbubna/store/master/src/store.dot.js
  142. [deep]: https://raw.github.com/nbubna/store/master/src/store.deep.js
  143. [dom]: https://raw.github.com/nbubna/store/master/src/store.dom.js
  144. [async]: https://raw.github.com/nbubna/store/master/src/store.async.js
  145. [cookie]: https://raw.github.com/nbubna/store/master/src/store.cookie.js
  146. [cookies]: https://raw.github.com/nbubna/store/master/src/store.cookies.js
  147. #### Write Your Own Extension
  148. To write your own extension, you can use or carefully override internal functions exposed as ```store._```.
  149. In particular, the ```store._.fn(fnName, fn)``` method is available to automatically add your new function
  150. to every instance of the ```store``` interface (e.g. ```store```, ```store.session```
  151. and all existing and future namespaces). Take care using this, as it will override existing methods.
  152. Here is a simple example:
  153. ```javascript
  154. (function(_) {
  155. _.fn('falsy', function(key) {
  156. return !this.get(key);
  157. });
  158. _.fn('truthy', function(key) {
  159. return !this.falsy(key);
  160. });
  161. })(store._);
  162. ```
  163. This extension would be used like so:
  164. ```javascript
  165. store('foo', 1);
  166. store.falsy('foo'); // returns false
  167. store.session('bar', 'one');
  168. store.session.truthy('bar'); // return true;
  169. const widgetStore = store.namespace('widget');
  170. widgetStore.falsy('state'); // returns true
  171. ```
  172. ## Release History
  173. * 2010-02-10 v0.1 (extraction from esha.js)
  174. * 2010-05-25 v1.0 (internal release)
  175. * 2013-04-09 [v2.0.3][] (public) - First GitHub release
  176. * 2013-04-20 [v2.1.0][] (public) - Drops flawed/confusing/unused key(i) method, fixes extension problems.
  177. * 2013-04-30 [v2.1.1][] (public) - Browserify (and friends) support (module.exports = store)
  178. * 2013-05-30 [v2.1.2][] (public) - Component support (old component.json is now bower.json)
  179. * 2014-03-10 [v2.1.6][] (public) - AMD support and Component improvements
  180. * 2015-02-02 [v2.2.0][] (public) - Change store.cache.js to use seconds, not minutes.
  181. * 2015-05-05 [v2.2.1][] (public) - node.js compatibility
  182. * 2015-05-08 [v2.2.2][] (public) - Always expose global to allow extensions to always work.
  183. * 2015-05-22 [v2.3.0][] (public) - Use fake storage for Safari private mode (instead of letting quota exceptions go)
  184. * 2015-10-27 [v2.3.2][] (public) - Add source map
  185. * 2017-01-04 [v2.4.0][] (public) - Add store.transact(key, fn[, alt])
  186. * 2017-01-09 [v2.5.0][] (public) - Update for issue #34; new extensions (array, dot, and deep); only expose global in non-AMD/CommonJS environments (PR #35)
  187. * 2017-08-09 [v2.5.2][] (public) - Fix `clear()` in fake storage (thx to Martin Kluska)
  188. * 2018-01-18 [v2.5.11][] (public) - Add ```index.d.ts``` in root to provide TypeScript support
  189. * 2018-01-23 [v2.6.0][] (public) - Support ```each(fn,value)```, ```getAll(fillObj)```, and ```keys(fillList)``` to support some advanced/corner cases
  190. * 2018-11-15 [v2.7.1][] (public) - Add ```add(key, data)``` for common case of saving a combination of existing and new data. Fix issue #60.
  191. * 2019-07-23 [v2.8.0][] (public) - Add ```store(fn)``` shortcut for ```store.each```, copy properties when inheriting, and make ```store.each(fn, fill)``` always send fill as 3rd arg instead of replacing values.
  192. * 2019-08-21 [v2.9.0][] (public) - Add store.remove(key, alt) to match behavior of store.get(key, alt) (Issue #68)
  193. * 2019-09-27 [v2.10.0][] (public) - Add ```store.page``` to provide page scope storage to complement local and session scope storage. (Issue #69)
  194. * 2020-03-23 [v2.11.0][] (public) - Add ```store.get(key, reviveFn)``` and ```store._.revive`` to support parsing for rich types (e.g. Date)
  195. * 2020-04-14 [v2.11.1][] (public) - Fix falsey alt value support in ```store.get(key, alt)```
  196. * 2020-05-11 [v2.11.2][] (public) - Fix missing TS declaration of new page scope storage.
  197. * 2020-08-12 [v2.12.0][] (public) - PRs for better Storage typing, better testKey, and dev dependency updates.
  198. * 2021-12-16 [v2.13.1][] (public) - Add ```store.set(key, value, replacerFn)```, ```store._replace```, and ```isFake([force])``` to support stringifying rich types and easier testing. And cookie-based extensions for using store backed by a single 'store' cookie or store API for all cookies.
  199. * 2022-03-14 [v2.13.2][] (public) - Restore missing TS declaration of store.area(id[, area])
  200. * 2022-05-11 [v2.14.0][] (public) - Allow namespace delimiter to be changed via store._.nsdelim
  201. * 2022-07-14 [v2.14.1][] (public) - Fix change to ```set``` that broke store.cache.js, and allow namespace delimiter to be passed to ```namespace(name, thisAreaOnly, delim)``` for a single namespace, to avoid conflicts.
  202. * 2022-07-18 [v2.14.2][] (public) - Fix typo in ```index.d.ts``` typings.
  203. * 2024-02-14 [v2.14.3][] (public) - Cut license options to just MIT, also removed Bower and Component support since those are long dead.
  204. * 2024-12-26 [v2.14.4][] (public) - Remove use of eval from store.deep.js
  205. [v2.0.3]: https://github.com/nbubna/store/tree/2.0.3
  206. [v2.1.0]: https://github.com/nbubna/store/tree/2.1.0
  207. [v2.1.1]: https://github.com/nbubna/store/tree/2.1.1
  208. [v2.1.2]: https://github.com/nbubna/store/tree/2.1.2
  209. [v2.1.6]: https://github.com/nbubna/store/tree/2.1.6
  210. [v2.2.0]: https://github.com/nbubna/store/tree/2.2.0
  211. [v2.2.1]: https://github.com/nbubna/store/tree/2.2.1
  212. [v2.2.2]: https://github.com/nbubna/store/tree/2.2.2
  213. [v2.3.0]: https://github.com/nbubna/store/tree/2.3.0
  214. [v2.3.2]: https://github.com/nbubna/store/tree/2.3.2
  215. [v2.4.0]: https://github.com/nbubna/store/tree/2.4.0
  216. [v2.5.0]: https://github.com/nbubna/store/tree/2.5.0
  217. [v2.5.2]: https://github.com/nbubna/store/tree/2.5.2
  218. [v2.5.11]: https://github.com/nbubna/store/tree/2.5.11
  219. [v2.6.0]: https://github.com/nbubna/store/tree/2.6.0
  220. [v2.7.1]: https://github.com/nbubna/store/tree/2.7.1
  221. [v2.8.0]: https://github.com/nbubna/store/tree/2.8.0
  222. [v2.9.0]: https://github.com/nbubna/store/tree/2.9.0
  223. [v2.10.0]: https://github.com/nbubna/store/tree/2.10.0
  224. [v2.11.1]: https://github.com/nbubna/store/tree/2.11.1
  225. [v2.11.2]: https://github.com/nbubna/store/tree/2.11.2
  226. [v2.12.0]: https://github.com/nbubna/store/tree/2.12.0
  227. [v2.13.1]: https://github.com/nbubna/store/tree/2.13.1
  228. [v2.13.2]: https://github.com/nbubna/store/tree/2.13.2
  229. [v2.14.0]: https://github.com/nbubna/store/tree/2.14.0
  230. [v2.14.1]: https://github.com/nbubna/store/tree/2.14.1
  231. [v2.14.2]: https://github.com/nbubna/store/tree/2.14.2
  232. [v2.14.3]: https://github.com/nbubna/store/tree/2.14.3
  233. [v2.14.4]: https://github.com/nbubna/store/tree/2.14.4