pasaran/descript — pull request #78 by edoroshenko (2014-03-25 12:22:53+00:00)
Title: Декларативная конструкция для гибкой работы со state

Возникло желание в декларативном стиле гибко работать с `context.state`.
Сейчас в блоках для этого существует секция `select`. Она поддерживает следующую нотацию:
```
{
prop1: 'jpath1',
...
propN: 'jpathN'
}
```
В результате обработки такой конструкции в свойства `prop1...propN` объекта `context.state` запишутся значения, выбранные из результата выполнения блока по `jpath1...jpathN` соответственно.

Недостатком этого подхода является тот факт, что он не позволяет формировать в `context.state` вложенные структуры объектов. Это удобно, когда в descript-приложении делается несколько запросов к бекенду и их результаты хочется многократно использовать в различных блоках.

В качестве решения я предлагаю добавить в декларацию блока секцию `state`, которая будет поддерживать 2 варианта нотации:
1) Функция. На входе у неё 2 аргумента:
- data - результат выполнения блока (до обработки секцией result)
- context
Объект, который вернёт функция, будет вмерджен (deep extend) в `context.state`.
```
de.object({
value1: true,
value3: false
}, {
state: function(data, context) {
return {
prop1: data.value1,
prop2: {
prop3: data.value3,
}
}
}
})
```
2) jresult - объект, содержайщий в значениях jpath, по которым при компилляции из результата работы объекта выбираются значения и подставляются в результирующий объект, которвый в свою очередь вмердживается (deep extend) в `state`
```
de.object({
value1: true,
value3: false
}, {
state: {
prop1: '.value1',
prop2: {
prop3: '.value3',
}
}
})
```

В результате обработки обоих вариантов в `state` попадёт объект
```
{
prop1: true,
prop2: {
prop3: false
}
}
```

Пример из жизни. Данные о пользователе я получаю из 2-х источников. Кроме этого, я делаю запрос в третий источник за другими данными.

Что хочется
1. Совместить данные о пользователе в едином объекте
2. Сделать раздел `models` в `context.state` и собирать там данные
3. Сделать эти действия декларативно

Как выглядит решение
```
de.array([
de.include('user-db1.jsx', {state: {
models: {
user: {
uid: '.uid',
emails: '.emails'
}
}
}}),
de.include('user-db2.jsx', {state: {
models: {
user: {
devices: '.devices',
settings: '.settings'
}
}
}}),
de.include('folders.jsx', {state: {
models: {
folders: '.'
}
}}),
])
```
В результате в `state` получится следующий объект:
```
{
models: {
user: {
uid: ...,
emails: ...,
devices: ...,
settings: ...
},
folders: {}
}
}
```

Потом сформулирую по-ангийски для wiki.