Skip to content

Commit f8fd20a

Browse files
authored
V2 (#175)
* Whitespace fix - no functional changes * Move all saucelabs scripts into a properly named folder * Implement 90% of store.js v2.0. The new architecture is fully backwards-compatible and supports pluggable functionality and storage engines. It comes out of the box with 6 storages: localStorage, sessionStorage, memoryStorage, cookieStorage, oldFF-globalStorage, oldIE-userDataStorage. It also comes with 7 addons: defaults for easy default values, events and observations for observing stored values, expire for auto-expiring stored values, operations for common array and object operations like push, pop, shift, assign, etc, update for easily updating an objects properties, and v1-backcompat for back-compatible behavior with store.js v1 * Clean up storage functions by removing the addon-prefix from the function names (they are no longer needed due to super_fn functionality) * Fix many previously failing tests. Getting clean and close to ready...!! * All tests pass! Looks like we have a release candidate! :) Time to write documentation and prep for release: clean up, test cross browser, write documentation, write announcement... * Move `has` to the backcompat addon, since it is not a necesary part of the store.js core API * Move store.dump into an addon, since it can be * Clean up store-engine.js. No functional changes * Start linting all store.js files using eslint. Caught lots of little bugs! * Move all source files into src/, remove old unused files, and misc clean ups * Remove outdated roadmap file * npm test -> make test * Simulate localStorage in node test runner * Fix expire_test, which was failing in browser * Misc cleanups * Fix cookieStorage.each * Add json2 addon for v1+json2 backcompatability * All tests passing for all modern storages. Saucelabs testing for legacy browser remains * Add `make build` which creates minified versions of each build in `build/*` * Clearly differentiate between util.Global and other environments mentions of global * Allow for storages to be passed in as a list or as an object * Use auto-formated package.json * Use tinytest.hijackConsoleLog * Add automation for running full cross-browser test suite on saucelabs * Add sublime project file * Use latest ngrok. It does not have the mutex lock bug of 0.2.2 * Fix test of addon expire. I have observed multiple times when legacy browsers in various environments (saucelabs, VMs, etc) have executed a scheduled timeout function too soon. The solution is to run a longer, timeout, but this substantially slows down the test suite. Instead, we allow multiple attempts with increasing durations. * Fix operations addon assign function, which behaved incorrectly if given the key of a non-object existing value * Fix operations addon test for array functions. When storing values containing arrays with `undefined` entries, JSON will serialize those entries as null. Thus, we should not test for proper behavior of adding `undefined` values to arrays * fix oldFF-glolalStorage implementation of `each` * Shortcut testing of oldIE-userDataStorage in IE8, IE9 and IE10 since it has a wonky implementation there which sometimes fails. In production this would not have an effect as long as localStorage is the prefered storage, since that is available in all three of those browsers * Fix oldIE-userDataStorage storage `each` implementation * === >>> == Exact equality is better suited here than loose equality * More informative success message on test suite completion * Print each line separately when listing all supported browsers, since the output is otherwise truncated * Remove executable mode of scripts/*.js to favor Makefile usage * Use latest tinytest with IE6 compatability * Fix expire addon tests, which I managed to botch somehow * Cleanup commit: Rename addons/mixins to plugins; Cleanup engine.js code organization; Remove storage.fixKey concept (it was only used by one storage); Add commas to the last property of object literals; Add two API functions: addStorage and addPlugin; Remove store.disabled, and move it to the v1-backcompat addon; Add build "cross-browser" * Exclude builds from sublime project * Allow require("store/plugins/X") and require("store/storages/X") by moving src/plugin to plugins and src/storage storages; Rename builds to dist * Changelog * Remove bower.json and component.json, since they are not widely used. We can add them back in if needed later * Update sublime project file to exclude dist * Make the default build "cross-browser" * Rename src/engine to src/store-engine to make it clearer what it is * Whitespace fix * Whitespace and trailing comma fixes * Fix oldFF-globalStorage name * Clean up builds * Simplify plugin writing by simply making it a function which returns the plugin function property object. * Remove old unused file from Makefile * Make build flags more explicit * Fix test scripts * Fix v1-backcompat plugin forEach * Cleanup saucelabs platform sets; add terminating commas to object literals in saucelabs platform sets * Add opera to browser test suite * Update builds * Point default build to src/builds/store.legacy * Update README.md * Allow for platform sets to specify a single version, as opposed to an array of versions * Fix build names in Changelog * Update saucelabs tunnel script test suite path name to match the build
1 parent 7479842 commit f8fd20a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+2730
-1482
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
node_modules
22
npm-debug.log
3+
*.sublime-workspace

Changelog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
v2.0.0
2+
+ New pluggable architecture!
3+
+ New storages: localStorage, cookieStorage, memoryStorage, sessionStorage, oldFF-globalStorage, oldIE-userDataStorage.
4+
+ New plugins: defaults, dump, events, expire, json2, observe, operations, update, v1-backcompat.
5+
+ New builds: everything, legacy, modern, v1-backcompat, minimal (17k, 13k, 12k, 6k respectively)
6+
17
v1.3.20
28
+ Fully automated test framework
39
+ Fix infinite loop in IE

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2010-2016 Marcus Westin
3+
Copyright (c) 2010-2017 Marcus Westin
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
test: test-node
2+
3+
test-node:
4+
node scripts/run-node-tests.js
5+
6+
test-browser:
7+
node scripts/run-browser-tests-live-reload.js
8+
9+
test-saucelabs: build
10+
node scripts/run-saucelabs-tests.js
11+
12+
tunnel:
13+
node scripts/create-tunnel.js
14+
15+
build: test lint
16+
node scripts/compile-builds.js
17+
18+
lint:
19+
./node_modules/.bin/eslint tests/* src/* \
20+
--ignore-pattern src/addon/lib/json2.js \

README-More.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
How does it work?
2+
------------------
3+
store.js uses localStorage when available, and falls back on the userData behavior in IE6 and IE7. No flash to slow down your page load. No cookies to fatten your network requests.
4+
5+
store.js depends on JSON for serialization to disk.
6+
7+
8+
Installation
9+
------------
10+
Just grab [store.min.js] or [store+json2.min.js] and include them with a script tag.
11+
12+
13+
`store.enabled` flag
14+
--------------------
15+
If your product depends on store.js, you must check the `store.enabled` flag first:
16+
17+
```html
18+
<script src="store.min.js"></script>
19+
<script>
20+
init()
21+
function init() {
22+
if (!store.enabled) {
23+
alert('Local storage is not supported by your browser. Please disable "Private Mode", or upgrade to a modern browser.')
24+
return
25+
}
26+
var user = store.get('user')
27+
// ... and so on ...
28+
}
29+
</script>
30+
```
31+
32+
LocalStorage may sometimes appear to be available but throw an error when used. An example is Safari's private browsing mode. Other browsers allow the user to temporarily disable localStorage. Store.js detects these conditions and sets the `store.enabled` flag appropriately.
33+
34+
35+
Screencast
36+
-----------
37+
[Introductory Screencast to Store.js](http://javascriptplayground.com/blog/2012/06/javascript-local-storage-store-js-tutorial) by Jack Franklin.
38+
39+
40+
Contributors & Forks
41+
--------------------
42+
Contributors: https://github.com/marcuswestin/store.js/graphs/contributors
43+
44+
Forks: https://github.com/marcuswestin/store.js/network/members
45+
46+
47+
In node.js
48+
----------
49+
store.js works as expected in node.js, assuming that global.localStorage has been set:
50+
51+
```
52+
global.localStorage = require('localStorage')
53+
var store = require('./store')
54+
store.set('foo', 1)
55+
console.log(store.get('foo'))
56+
```
57+
58+
59+
Supported browsers
60+
------------------
61+
- Tested in iOS 4+
62+
- Tested in Firefox 3.5
63+
- Tested in Firefox 3.6
64+
- Tested in Firefox 4.0+
65+
- Support dropped for Firefox < 3.5 (see notes below)
66+
- Tested in Chrome 5
67+
- Tested in Chrome 6
68+
- Tested in Chrome 7
69+
- Tested in Chrome 8
70+
- Tested in Chrome 10
71+
- Tested in Chrome 11+
72+
- Tested in Safari 4
73+
- Tested in Safari 5
74+
- Tested in IE6
75+
- Tested in IE7
76+
- Tested in IE8
77+
- Tested in IE9
78+
- Tested in IE10
79+
- Tested in Opera 10
80+
- Tested in Opera 11
81+
- Tested in Opera 12
82+
- Tested in Node.js v0.10.4 (with https://github.com/coolaj86/node-localStorage 1.0.2)
83+
84+
*Private mode* Store.js may not work while browsing in private mode. This is as it should be. Check the `store.enabled` flag before relying on store.js.
85+
86+
*Saucelabs.com rocks* Extensive browser testing of store.js is possible thanks to Saucelabs.com. Check them out, they're awesome.
87+
88+
*Firefox 3.0 & 2.0:* Support for FF 2 & 3 was dropped in v1.3.6. If you require support for ancient versions of FF, use v1.3.5 of store.js.
89+
90+
*Important note:* In IE6 and IE7, many special characters are not allowed in the keys used to store any key/value pair. With [@mferretti](https://github.com/mferretti)'s help, there's a suitable workaround which replaces most forbidden characters with "___".
91+
92+
93+
Storage limits
94+
--------------
95+
- IE6 & IE7: 1MB total, but 128kb per "path" or "document" (see http://msdn.microsoft.com/en-us/library/ms531424(v=vs.85).aspx)
96+
- See http://dev-test.nemikor.com/web-storage/support-test/ for a list of limits per browser
97+
98+
Unsupported browsers
99+
-------------------
100+
- Firefox 1.0: no means (beside cookies and flash)
101+
- Safari 2: no means (beside cookies and flash)
102+
- Safari 3: no synchronous api (has asynch sqlite api, but store.js is synch)
103+
- Opera 9: don't know if there is synchronous api for storing data locally
104+
- Firefox 1.5: don't know if there is synchronous api for storing data locally
105+
- Microsoft IIS & IE7: With meta tag & "charset=iso-8859-1", things stop working. See issue #47.
106+
107+
108+
Some notes on serialization
109+
---------------------------
110+
localStorage, when used without store.js, calls toString on all stored values. This means that you can't conveniently store and retrieve numbers, objects or arrays:
111+
112+
```js
113+
localStorage.myage = 24
114+
localStorage.myage !== 24
115+
localStorage.myage === '24'
116+
117+
localStorage.user = { name: 'marcus', likes: 'javascript' }
118+
localStorage.user === "[object Object]"
119+
120+
localStorage.tags = ['javascript', 'localStorage', 'store.js']
121+
localStorage.tags.length === 32
122+
localStorage.tags === "javascript,localStorage,store.js"
123+
```
124+
125+
What we want (and get with store.js) is
126+
127+
```js
128+
store.set('myage', 24)
129+
store.get('myage') === 24
130+
131+
store.set('user', { name: 'marcus', likes: 'javascript' })
132+
alert("Hi my name is " + store.get('user').name + "!")
133+
134+
store.set('tags', ['javascript', 'localStorage', 'store.js'])
135+
alert("We've got " + store.get('tags').length + " tags here")
136+
```
137+
138+
The native serialization engine of javascript is JSON. Rather than leaving it up to you to serialize and deserialize your values, store.js uses JSON.stringify() and JSON.parse() on each call to store.set() and store.get(), respectively.
139+
140+
Some browsers do not have native support for JSON. For those browsers you should include [JSON2.js] \(non-minified copy is included in this repo).
141+
142+
143+
No sessionStorage/auto-expiration?
144+
----------------------------------
145+
No. I believe there is no way to provide sessionStorage semantics cross browser. However, it is trivial to expire values on read on top of store.js:
146+
147+
```js
148+
var storeWithExpiration = {
149+
set: function(key, val, exp) {
150+
store.set(key, { val:val, exp:exp, time:new Date().getTime() })
151+
},
152+
get: function(key) {
153+
var info = store.get(key)
154+
if (!info) { return null }
155+
if (new Date().getTime() - info.time > info.exp) { return null }
156+
return info.val
157+
}
158+
}
159+
storeWithExpiration.set('foo', 'bar', 1000)
160+
setTimeout(function() { console.log(storeWithExpiration.get('foo')) }, 500) // -> "bar"
161+
setTimeout(function() { console.log(storeWithExpiration.get('foo')) }, 1500) // -> null
162+
```
163+
164+
165+
166+
[JSON2.js]: https://raw.githubusercontent.com/douglascrockford/JSON-js/master/json2.js
167+
[store.min.js]: https://raw.github.com/marcuswestin/store.js/master/store.min.js
168+
[store+json2.min.js]: https://raw.github.com/marcuswestin/store.js/master/store+json2.min.js
169+

0 commit comments

Comments
 (0)