Comparing version 0.8.0-beta to 0.8.0
{ | ||
"name": "marty", | ||
"main": "dist/marty.js", | ||
"version": "0.8.0-beta", | ||
"version": "0.8.0", | ||
"homepage": "martyjs.org", | ||
@@ -6,0 +6,0 @@ "authors": [ |
@@ -20,12 +20,9 @@ --- | ||
<h3 id="mixins">mixins</h3> | ||
An (optional) array of mixins that can be passed in through the createStateSource method. | ||
<h3 id="type">type</h3> | ||
<h3 id="name">name</h3> | ||
The type of the state source (e.g. 'http'). | ||
An (optional) display name for the repository. Used for richer debugging. | ||
<h3 id="mixins">mixins</h3> | ||
<h3 id="type">type</h3> | ||
An (optional) type for the repository (e.g. 'http'). Used for richer debugging. | ||
An (optional) array of mixins that can be passed in through the createStateSource method. |
@@ -43,2 +43,5 @@ --- | ||
}, | ||
getInitialState: function () { | ||
return {}; | ||
}, | ||
addUser: function (user) { | ||
@@ -88,2 +91,5 @@ console.log(this.action) // { type: 'RECEIVE_USER', arguments: [{ name: ...}] } | ||
}, | ||
getInitialState: function () { | ||
return {}; | ||
}, | ||
addUser: function (user) { | ||
@@ -104,6 +110,4 @@ this.state.push(user); | ||
<code>getInitialState</code> is called when the store is first instantiated. It expects you to pass an object back which represents the stores state. The value you return will subsequently be available from the [state](#state) property. | ||
<code>getInitialState</code> (*required*) is called when the store is first instantiated. It expects you to pass an object back which represents the stores state. The value you return will subsequently be available from the [state](#state) property. | ||
If you do not implement getInitialState or you do not return anything then the default state is an empty object literal (<code>{}</code>). | ||
<h2 id="state">state</h2> | ||
@@ -277,3 +281,3 @@ | ||
<h3>Fetch Result</h3> | ||
<h3 id="fetch-result">Fetch Result</h3> | ||
@@ -280,0 +284,0 @@ Fetch returns a result object that repesents the current state of the fetch. It has a status which can be either **PENDING**, **DONE** OR **FAILED**. You can get the status by accessing ``fetch.status`` or with the helpers ``fetch.pending``, ``fetch.failed`` or ``fetch.done``. |
@@ -23,2 +23,2 @@ --- | ||
Initially it only generates the basic folder structure. You can use <code>yo marty:domain {domain name}</code> to automatically create an action creator, store, constants, HTTP API and component for the given domain. | ||
Initially it only generates the basic folder structure. You can use <code>yo marty:domain {domain name}</code> to automatically create an action creator, store, constants, state source and component for the given domain. |
--- | ||
layout: page | ||
title: HTTP | ||
title: HTTP State Source | ||
id: http-state-source | ||
@@ -8,6 +8,4 @@ section: State Sources | ||
It's likely at some point that you will need to communicate with the server. HTTP APIs encapsulate that communication for you. | ||
The HTTP state source makes it easy to talk to remote servers over HTTP. We use the [fetch](https://github.com/github/fetch) polyfill for making requests but you can use easily roll your own if you like. | ||
HTTP APIs allow you to define functions that create HTTP requests. We use the [fetch](https://github.com/github/fetch) polyfill for making requests but you can use easily roll your own if you like. | ||
All requests return a promise (Promises/A) that allow you to easily define what happens when a request has finished. | ||
@@ -14,0 +12,0 @@ |
@@ -8,1 +8,26 @@ --- | ||
State sources are how you get state into and out of your application. State can come from many different places (e.g. API's, Web sockets, Local Storage), State sources encapsulate a lot of complexities in connecting to these sources and provides a uniform, easy to test interface for the rest of your application to use. | ||
{% highlight js %} | ||
var UserAPI = Marty.createStateSource({ | ||
type: 'socket.io', | ||
baseUrl: 'http://foo.com', | ||
getUsers: function () { | ||
return this.get('/users').then(function (res) { | ||
SourceActionCreators.receiveUsers(res.body); | ||
}); | ||
}, | ||
createUser: function (user) { | ||
return this.pose('/users', { body: user }); | ||
} | ||
}); | ||
UserAPI.getUsers(); | ||
{% endhighlight %} | ||
Marty comes with a number of state sources out of the box: | ||
* [HTTP](/guides/state-sources/http.html) | ||
* [JSON storage](/guides/state-sources/json-storage.html) | ||
* [Local storage](/guides/state-sources/local-storage.html) | ||
* [Session storage](/guides/state-sources/session-storage.html) |
--- | ||
layout: page | ||
title: JSON storage | ||
title: JSON Storage State Source | ||
id: json-storage-state-source | ||
section: State Sources | ||
--- | ||
--- | ||
The JSON Storage State Source allows you to persist objects to [localStorage](https://developer.mozilla.org/en/docs/Web/Guide/API/DOM/Storage#localStorage) or [sessionStorage](https://developer.mozilla.org/en/docs/Web/Guide/API/DOM/Storage#sessionStorage), handling serialisation for you. | ||
{% highlight js %} | ||
var UserStorage = Marty.createStateSource({ | ||
type: 'jsonStorage', | ||
storage: window.sessionStorage, | ||
saveUser: function (user) { | ||
this.set(user.id, user); | ||
}, | ||
getUser: function (userId) { | ||
return this.get(userId); | ||
} | ||
}); | ||
UserStorage.saveUser({id: 123, name: 'Foo'}); | ||
{% endhighlight %} |
--- | ||
layout: page | ||
title: Local storage | ||
title: Local Storage State Source | ||
id: local-storage-state-source | ||
section: State Sources | ||
--- | ||
--- | ||
The Local Storage State Source allows you to persist data to [localStorage](https://developer.mozilla.org/en/docs/Web/Guide/API/DOM/Storage#localStorage). | ||
{% highlight js %} | ||
var FooStorage = Marty.createStateSource({ | ||
type: 'localStorage', | ||
saveFoo: function (foo) { | ||
this.set('foo', foo); | ||
}, | ||
getFoo: function () { | ||
return this.get('foo'); | ||
} | ||
}); | ||
FooStorage.getFoo(); | ||
{% endhighlight %} |
--- | ||
layout: page | ||
title: Session storage | ||
title: Session Storage State Source | ||
id: session-storage-state-source | ||
section: State Sources | ||
--- | ||
--- | ||
The Session Storage State Source allows you to persist data to [sessionStorage](https://developer.mozilla.org/en/docs/Web/Guide/API/DOM/Storage#sessionStorage). | ||
{% highlight js %} | ||
var FooStorage = Marty.createStateSource({ | ||
type: 'sessionStorage', | ||
saveFoo: function (foo) { | ||
this.set('foo', foo); | ||
}, | ||
getFoo: function () { | ||
return this.get('foo'); | ||
} | ||
}); | ||
FooStorage.saveFoo('Foo'); | ||
{% endhighlight %} |
@@ -24,3 +24,14 @@ --- | ||
this.hasChanged(); | ||
}, | ||
} | ||
}); | ||
{% endhighlight %} | ||
A store is a singleton which is created using [<code>Marty.createStore</code>](/api/stores/index.html#createStore). When the store is created it will call [<code>getInitialState</code>](/api/stores/index.html#getInitialState) which should return an object that all the stores state will live in. This state is accessible by calling <code>this.state</code>. | ||
When an action is dispatched, the store will check its [``handlers`` hash](/api/stores/index.html#handlers) to see if the store has a handler for the actions type. If it does it will call that handler, passing in the actions data. If the handler updates the stores state state, it can call [<code>hasChanged</code>](/api/stores/index.html#hasChanged) which will notify any listening views of its new state. | ||
If your view needs some state it should request it from the relevant store. If the store doesn't have it locally it should get it from a [state source](/guides/state-sources/index.html). The [fetch](/api/stores/index.html#fetch) API helps you define how to get the state locally and remotely. ``fetch`` requires 3 things: An Id that uniquely identifies the bit of state you are fetching (e.g. a user Id), a function to try and get the state from the store (``locally``) and a function to get the state from a state source (``remotely``). | ||
{% highlight js %} | ||
var UsersStore = Marty.createStore({ | ||
getUser: function (id) { | ||
@@ -40,6 +51,18 @@ return this.fetch({ | ||
A store is a singleton which is created using [<code>Marty.createStore</code>](/api/stores/index.html#createStore). When the store is created it will call [<code>getInitialState</code>](/api/stores/index.html#getInitialState) which should return an object that all the stores state will live in. This state is accessible by calling <code>this.state</code>. | ||
The ``fetch`` function will first try calling the ``locally`` function. If it returns a value then it will immediately return. If it returns null or undefined then it will call the ``remotely`` function. Once ``remotely`` is finished executing then ``locally`` is then re-called with the expectation that the state should now be in the store. If ``remotely`` returns a promise then ``locally`` will be reinvoked once the promise resolves. | ||
When an action is dispatched, the store will check its [``handlers`` hash](/api/stores/index.html#handlers) to see if the store has a handler for the actions type. If it does it will call that handler, passing in the actions data. If the handler updates the stores state state, it can call [<code>hasChanged</code>](/api/stores/index.html#hasChanged) which will notify any listening views of its new state. | ||
The result of the ``fetch`` function is a [fetch result](http://localhost:4000/api/stores/#fetch-result) which represents the current state of the fetch. The 3 states a fetch result can be in is **PENDING**, **DONE** OR **FAILED**. You can use ``FetchResult#when`` to switch between the 3 states | ||
If your view needs some data, it should request it from the relevant store. The store is responsible for sourcing it, either locally or from the server. The [fetch](/api/stores/index.html#fetch) API helps simplify handling async operations. | ||
{% highlight js %} | ||
var component = UserStore.getUser(123).when({ | ||
pending: function () { | ||
return <Loading />; | ||
}, | ||
failed: function (error) { | ||
return <ErrorPage error={error} />; | ||
}, | ||
done: function (user) { | ||
return <div className="user">{user.name}</div>; | ||
} | ||
}); | ||
{% endhighlight %} |
@@ -7,3 +7,3 @@ var _ = require('underscore'); | ||
var Marty = _.extend({ | ||
version: '0.8.0-beta', | ||
version: '0.8.0', | ||
Dispatcher: Dispatcher.getCurrent() | ||
@@ -10,0 +10,0 @@ }, state, create); |
@@ -32,3 +32,3 @@ require('isomorphic-fetch'); | ||
if (isJson(res)) { | ||
if (isJson(res) && res._body) { | ||
res.body = JSON.parse(res._body); | ||
@@ -35,0 +35,0 @@ } |
@@ -13,2 +13,4 @@ var CHANGE_EVENT = 'changed'; | ||
var ActionPredicateUndefinedError = require('../errors/actionPredicateUndefined'); | ||
var REQUIRED_FUNCTIONS = ['getInitialState']; | ||
var RESERVED_FUNCTIONS = ['dispose', 'clear']; | ||
@@ -37,3 +39,2 @@ | ||
this.handleAction = handleAction; | ||
this.getInitialState = getInitialState; | ||
this.addChangeListener = addChangeListener; | ||
@@ -48,2 +49,3 @@ | ||
validateOptions(options); | ||
extendStore(this, _.omit(options, RESERVED_FUNCTIONS)); | ||
@@ -68,2 +70,16 @@ validateHandlers(this); | ||
function validateOptions(options) { | ||
var errors = []; | ||
_.each(REQUIRED_FUNCTIONS, function (functionName) { | ||
if (!_.has(options, functionName)) { | ||
errors.push('You must implement ' + functionName); | ||
} | ||
}); | ||
if (errors.length) { | ||
throw new Error(errors.join('. ')); | ||
} | ||
} | ||
function validateHandlers(store) { | ||
@@ -96,6 +112,2 @@ _.each(store.handlers, function (actionPredicate, handlerName) { | ||
function getInitialState() { | ||
return defaultState; | ||
} | ||
function dispose() { | ||
@@ -102,0 +114,0 @@ emitter.removeAllListeners(CHANGE_EVENT); |
{ | ||
"name": "marty", | ||
"version": "0.8.0-beta", | ||
"version": "0.8.0", | ||
"description": "A React.js/Flux Framework", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1566150
129
23862