# MangoJuice Core

## Reference

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

#### Table of Contents

-   [Basic](#basic)
    -   [Block](#block)
    -   [LogicBase](#logicbase)
        -   [config](#config)
        -   [children](#children)
        -   [computed](#computed)
        -   [port](#port)
        -   [hubAfter](#hubafter)
        -   [hubBefore](#hubbefore)
    -   [cmd](#cmd)
    -   [run](#run)
    -   [mount](#mount)
    -   [task](#task)
    -   [cancel](#cancel)
    -   [child](#child)
    -   [depends](#depends)
-   [Extras](#extras)
    -   [Process](#process)
        -   [bind](#bind)
        -   [run](#run-1)
        -   [destroy](#destroy)
        -   [exec](#exec)
        -   [finished](#finished)
    -   [Command](#command)
        -   [exec](#exec-1)
        -   [clone](#clone)
        -   [is](#is)
        -   [appendArgs](#appendargs)
        -   [bind](#bind-1)
    -   [TaskMeta](#taskmeta)
        -   [notify](#notify)
        -   [success](#success)
        -   [fail](#fail)
        -   [multithread](#multithread)
        -   [engine](#engine)
        -   [args](#args)
    -   [DefaultLogger](#defaultlogger)
        -   [onStartExec](#onstartexec)
        -   [onStartHandling](#onstarthandling)
        -   [onEndHandling](#onendhandling)
        -   [onExecuted](#onexecuted)
        -   [onEndExec](#onendexec)
        -   [onCatchError](#oncatcherror)
    -   [ComputedField](#computedfield)
        -   [compute](#compute)
    -   [Mounter](#mounter)
    -   [defineCommand](#definecommand)
    -   [ensureCommand](#ensurecommand)
    -   [decorateLogic](#decoratelogic)
    -   [handleBefore](#handlebefore)
    -   [handleAfter](#handleafter)
    -   [handle](#handle)
    -   [logicOf](#logicof)
    -   [observe](#observe)
    -   [procOf](#procof)
    -   [bind](#bind-2)
    -   [hydrate](#hydrate)
    -   [delay](#delay)

### Basic

The most common APIs that you will work with most of the time


#### Block

Block is a top level component in MangoJuice which consists of three parts:

-   Model factory function `createModel` which should return a plain object.
    The main requirement for this function is that it should be able to return
    some model with zero arguments. But it can also accept some arguments
    as well.
-   A logic class which implements [LogicBase](#logicbase) interface
-   A View function which is aimed to render the model created by `createModel`

The View part is optional and it could have different type depending on
selected View library to render a model and particular binding library.

**Properties**

-   `Logic` **[LogicBase](#logicbase)** A logic class that should be attached to the model.
-   `createModel` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that shuld return a plain object which
                                      will be an init model of the block.
-   `View` **any?** Something that some particular view library can render

**Examples**

```javascript
// You can define block in short way using an object
const MyBlock = {
  createModel: () => ({ field: 1 }),
  Logic: class MyLogic {
    \@cmd SomeCommand() {
      return { field: this.model.field + 1 };
    }
  },
  View: ({ model }) => (
    <div>{model.field}</div>
  )
};

run(MyBlock);
```

```javascript
// Or you can split it with modules (recommended)
// ./MyBlock/index.js
import Logic from './Logic';
import View from './View';
import { createModel } from './Model';
export default { View, Logic, createModel };
export { View, Logic, createModel };
export type { Model } from './Model';

// ./MyBlock/Logic.js
import type { Model } from './Model';
import { LogicBase, cmd } from 'mangojuice-core';

export default class MyLogic extends LogicBase<Model> {
  \@cmd SomeCommand() {
    return { field: this.model.field + 1 };
  }
}

// ./MyBlock/Model.js
export type Model = { field: number };
export const createModel = () => ({
  field: 1
});

// ./MyBlock/View.js
const MyBlockView = ({ model }) => (
  <div>{model.field}</div>
);
export default MyBlockView;

// ./index.js
import MyBlock from './MyBlock';
import { run } from 'mangojuice-core';

run(MyBlock);
```

#### LogicBase

Basic class for every logic. It is not necessaty to inherit an actual logic
class from it, but for better type-checking it could be really usefull.

Logic class defines:

-   A set of commands that could change an associated model – methods decorated with [cmd](#cmd)
-   What fields of the model should be associated with which logic class
    (children blocks) – [LogicBase#children](#logicbasechildren) method
-   A set of computed model fields – [LogicBase#computed](#logicbasecomputed) method
-   A set of rules to handle commands from children logic – [LogicBase#hubAfter](#logicbasehubafter)
    and [LogicBase#hubBefore](#logicbasehubbefore) methods
-   A logic to handle external events – [LogicBase#port](#logicbaseport) method.

The logic class defines all the business-logic of some part of your application.
The main goal of the logic – change associated model. Check [cmd](#cmd) and [Process#exec](#processexec)
to have a better understanding how command can be defined and how it is executed.

**Properties**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object which is associated with the
                               logic class in parent logic.
-   `meta` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** An object defined in [LogicBase#config](#logicbaseconfig) method for storing
                               some internal logic state.
-   `shared` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** An object with some shared state, defined while
                               run process of the app.

**Examples**

```javascript
// ./blocks/MyBlock/Logic.js
// @flow
import type { Model } from './Model';
import ChildBlock from '../ChildBlock';
import { Command, cmd } from 'mangojuice-core';

export default class MyLogic extends LogicBase<Model> {
  children() {
    return { child: ChildBlock.Logic };
  }
  hubAfter(cmd: Command) {
    if (cmd.is(ChildBlock.Logic.prototype.SomeCommand)) {
      return this.TestCommand(123);
    }
  }
  \@cmd TestCommand(arg) {
    return { field: arg + this.model.field };
  }
}
```

##### config

A function that defines init commands and meta object of the
logic. Can accept any type and number of arguments. Config
will take arguments passed to [child](#child) function (for example
`child(MyLogic, 1, 2, 3)` defines that the `config` method of
`MyLogic` will be invoked like `config(1, 2, 3)`)

Could return an object with the fields:

-   `initCommands` which could be an array or a single Command,
    that will be executed every time when the logic instance created
    and associated with some model (when [Process#run](#processrun) invoked)
-   `meta` which could be an object with some internal state of
    the logic

**Examples**

```javascript
config(props) {
  return {
    initCommands: [ this.StartThis, this.SendThat(123) ],
    meta: { something: props.amount }
  };
}
```

##### children

This function defines what logic class should be associated
with which model field. Should return an object where a key is
a model field name, and a value is a logic class or an object
that defines logic with arguments (return from [child](#child) function)

**Examples**

```javascript
children() {
  return {
    searchForm: child(SearchForm.Logic, { timeout: 100 }),
    searchResults: SearchResults.Logic
  };
}
```

Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** 

##### computed

Should return an object which defines computed fields of the model.
A key of the object is a model field, and value is a function or
computed function definition object (return from [depends](#depends) function).

Computed field is lazy, which means that it is computed on the first use
of the field and the computation result cached until the next update
of the model.

If you want to define a computed field which ueses in computation not
only fields from the own model, but maybe some values from child model,
or from shared model, then you will need to use [depends](#depends) function to
define what models used while computation to observe changes of these
models to trigger an update event of the own model (to update views).

**Examples**

```javascript
computed() {
  return {
    simple: () => this.model.a + this.model.b,
    withDeps: depends(this.model.child, this.shared).compute(() => {
      return this.model.child.a + this.shared.b + this.model.c;
    })
  };
}
```

Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** 

##### port

A function to handle global event, such as browser-level events,
websocket, intervals. The main porpouse of the `port` is to subscribe
to some global events, execute appropriate commands from the logic
on the events and remove the handlers when the logic was destroyed.

**Parameters**

-   `exec` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** It is a function that execute a passed command
-   `destroyed` **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** A promise that will be resolved when the logic destroyed

**Examples**

```javascript
port(exec, destroyed) {
  const timer = setInterval(() => {
    exec(this.SecondPassed);
  }, 1000);
  destroyed.then(() => clearInterval(timer));
}
```

##### hubAfter

Hub for all commands executed in the children blocks. The only
arguments is a command object that was executed.
Could return a Command or an array of Commands that should
be executed next.
Most of the time this function will look like a `switch`,
but maybe with some additional rules for the cases. Take a look
to [Command#is](#commandis) function to have a better understanding how you
can determine that the command is exactly what you are waiting for.

**Parameters**

-   `cmd` **[Command](#command)** Command that was executed in some child logic
                           or in any child of the child and so on down to
                           the leaf of the tree.

**Examples**

```javascript
hubAfter(cmd) {
  if (cmd.is(ChildBlock.Logic.prototype.SomeCommand)) {
    return this.HandlerCommand(123);
  }
  if (cmd.is('AnotherChild.SomeAnothercommand')) {
    return [ this.HandlerCommand(321), this.AnotherHandler ];
  }
}
```

Returns **([Command](#command)? | [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Command](#command)>?)** 

##### hubBefore

Same as [LogicBase#hubAfter](#logicbasehubafter), but catch commands before
it will be actually executed, so you can compare prev and next
model state for example.

**Parameters**

-   `cmd` **[Command](#command)** 

Returns **([Command](#command)? | [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Command](#command)>?)** 

#### cmd

Decorator that converts a logic method to a command factory.
The result function (command factory function) is a function
that return a [Command](#command) instnace with the decorated function
and arguments that you will pass to a command factory function.

You can use this decorator without arguments or with an options
argument (object)

Check [Process#exec](#processexec) to see what the origin function
could return to do something. If in short, it can return:
nothing, command (or factory or array of commands), task,
model update object.

**Parameters**

-   `obj` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** If only this argument passed then it will be considered
                                   as options object which can customize command behaviour.
    -   `obj.debounce` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** If greeter than zero then an exeuction
                                       of the command will be debounced by given amount of
                                       milliseconds
    -   `obj.throttle` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** If greeter than zero then an exeuction
                                       of the command will be throttled by given amount of
                                       milliseconds
    -   `obj.noInitCall` **bool** If true then debounced/throttled execution
                                       won't start with init command call. By default
                                       debounced/throttled command will be instantly
                                       exected and only then wait for a chance to execute
                                       again. With `noInitCall=true` there is no instant init
                                       command call.
    -   `obj.internal` **bool** Make the command invisible for parent [LogicBase#hubBefore](#logicbasehubbefore)
                                       and [LogicBase#hubAfter](#logicbasehubafter). Use it for commands that shouldn't
                                       be handled by hubs to increse performance.
    -   `obj.name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** By default name of the command taken from origin function. With this
                                       option you can override the name with any other value.
-   `methodName`  
-   `descr`  

**Examples**

```javascript
class RegularLogic {
  \@cmd RegularCommand() {
    // do something
  }
}
```

```javascript
class RegularLogic {
  \@cmd({ debounce: 300 })
  DebouncedCommand() {
    // if you will call this command 3 times every
    // 100ms then it will be executed 2 times,
    // first right when you call it for a first time,
    // and second in 600ms.
  }
}
```

```javascript
class RegularLogic {
  \@cmd({ throttle: 300 })
  ThrottledCommand() {
    // if you will call this command 3 times every
    // 100ms then it will be executed 2 times,
    // first right when you call it for a first time,
    // and second in 300ms.
  }
}
```

```javascript
class RegularLogic {
  \@cmd({ throttle: 300, noInitCall: true })
  ThrottledCommand() {
    // if you will call this command 3 times every
    // 100ms then it will be executed 1 time in 300ms.
  }
}
```

```javascript
class RegularLogic {
  \@cmd({ internal: true })
  _InternalCommand() {
    // this command can't be caught in `hubBefore` or `hubAfter`
    // in parent logics. Use it carefully.
  }
}
```

Returns **([Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) \| [object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object))** Command factory function (if all three arguemnts passed)
                               or a decorator function with binded options object
                               (that you pass as a first argument)

#### run

Run given block. It is a short-hand function for running [bind](#bind)
and then running a Process by [Process#run](#processrun).
Also it returns an additional `finished` Promise which is resolved
when all async tasks finished and all handler commands executed.

**Parameters**

-   `block` **[Block](#block)** A block that you wan to run
-   `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Same options as in [bind](#bind) (optional, default `{}`)

Returns **{proc: [Process](#process), model: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), block: [Block](#block), finished: [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)}** An object
                 which is almost the same as returned from [bind](#bind), but with
                 additional `finished` field, which is a Promise that will be resolved
                 when all blocks will execute all commands and all async tasks will be
                 finished.

#### mount

Mount running block. As third and next arguments you can pass other running
blocks which will be stopped with the main running block (useful for HMR).

**Parameters**

-   `mounter` **[Mounter](#mounter)** An implementation of [Mounter](#mounter) interface
-   `runRes` **{proc: [Process](#process), block: [Block](#block), model: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)}** An object that returned
                     from [run](#run) function.
-   `otherBlocks` **...any** 

**Examples**

```javascript
const MyBlock = {
  createModel: () => ({ field: 1 }),
  Logic: class MyLogic {
    \@cmd SomeCommand() {
      return { field: this.model.field + 1 };
    }
  },
  View: ({ model }) => (
    <div>{model.field}</div>
  )
};

mount(new ReactMounter(), run(MyBlock));
```

Returns **{view: any, stop: [Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)}** An object with the result form [Mounter#mount](Mounter#mount)
                 function (in `view` field) and stop function which destroy the process and
                 unmount a view using [Mounter#unmount](Mounter#unmount)

#### task

Creates a [TaskMeta](#taskmeta) object that could be returned from
async task command. It describes the task that should be executed.

For more information what the **Task** is and how it should be implemented
take a look to [TaskMeta](#taskmeta).

**Parameters**

-   `taskFn` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that could return a Promise

**Properties**

-   `CANCEL` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** A symbol that you can use to make a promise "cancellable"

Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** 

#### cancel

This function should be used to cancel async [task](#task) execution.
Also it can cancel the debounced/throttled command.

-   In case with task, if task was executing while you call a cancel command,
    the task will be cancelled (execution stopped). Otherwise nothing will happen.
-   In case with debounced/throttled command, if the command scheduled to be executed
    then the schedule timer will be cleared and the command won't be executed.
    If the command is not scheduled then nothing happens.

To use it just pass a command or command factory as a first argument
and return it from some other command.

**Parameters**

-   `cmd` **([Command](#command) \| [function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function))** Command or command factory that you wan to cancel. Could
                                    be a command that returns [task](#task) or debounced/throttled
                                    command

**Examples**

```javascript
class SomeLogic {
  \@cmd CancelSomethingCommand() {
    return [
      cancel(this.TaskCommand),
      cancel(this.DebounceCommand)
    ];
  }
  \@cmd TaskCommand() {
    return task(Tasks.SomeTask);
  }
  \@cmd({ debounce: 300 })
  DebounceCommand() {
    // do something
  }
}
```

Returns **[Command](#command)** Returns a new command that will cancel the execution of the command
                  passed as an argument.

#### child

Creates an object which describes child logic which will be attached
to some model field. Should be used in [LogicBase#children](#logicbasechildren) to
define a logic that should be instantiated with some arguments passed
to [LogicBase#config](#logicbaseconfig).

**Parameters**

-   `logicClass` **[LogicBase](#logicbase)** Class that imlements [LogicBase](#logicbase) interface
-   `args` **...any** 

**Examples**

```javascript
class ChildLogic {
  config(amount) {
    return { meta: { amount } };
  }
}
class RootLogic {
  children() {
    return {
      modelField: child(ChildLogic, 10)
      // `config` of `ChildLogic` will be invoked with
      // `10` as a first argument
    }
  }
}
```

Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object that contains a logic class and an arguments array that
                 should be used to invoke `config` method of provided logic class.

#### depends

Function that helps to describe a computed field with external
model dependncies. Should be used in [LogicBase#computed](#logicbasecomputed).
It creates an instance of [ComputedField](#computedfield) with dependencies
passed as arguments.

A compute field with external dependencies is a field that should
be updated (re-computed) not only when the own model udpated, but
also when depdendency models updated.

**Parameters**

-   `deps` **...deps** A list of models with attached logic

**Examples**

```javascript
class ChildLogic {
  // some logic
}
class MyLogic {
  children() {
    return { childModel: ChildLogic };
  }
  computed() {
    return {
      // depends on `childModel`
      computedField: depends(this.model.childModel).compute(() => {
        return this.model.a + this.model.childModel.b;
      }),

      // depends on `shared` model
      computeWithShared: depends(this.shared).compute(() => {
        return this.model.b + this.shared.someField;
      })
    }
  }
}
```

Returns **[ComputedField](#computedfield)** 

### Extras

Other pieces of MangoJuice


#### Process

The main class of MangoJuice that ties model, logic and view together.

It works in the following way:

-   You create a model for your app (object) using `createModel` of
    the root block. The result is a plain object.
-   Then you need to create an instance of Process and pass logic class
    in the options object.
-   Then you `bind` the Process instance to the model object you created on step one.
    "To bind Process to a model" means that in the model will be created a hidden
    field `__proc` with a reference to the Process instance.
-   After that you can `run` the Process, which will execute init commands, port.

`bind` and `run` also look at the object returned from [LogicBase#children](#logicbasechildren)
and create/run Process instances for children models.

Most of the time you do not need to care about all of these and just use
[run](#run) and [mount](#mount). These small functions do everything described
above for you.

**Examples**

```javascript
import { Process, logicOf } from 'mangojuice-core';

const ExampleBlock = {
  createModel() {
    return { a: 10 };
  },
  Logic: class Example {
    \@cmd Increment(amount = 1) {
      return { a: this.model.a + amount };
    }
  }
};

const model = ExampleBlock.createModel();
const proc = new Process({ logic: ExampleBlock.Logic });
proc.bind(model);
proc.run();
proc.exec(logicOf(model).Increment(23));
```

##### bind

Bind the process instance to a given model, which means that hidden
`__proc` field will be created in the model with a reference to the
Process instance.

Also bind all children models – go through children definition returned
by [LogicBase#children](#logicbasechildren), create Process for each child and bind
it to an appropreat child model object.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object that you want to bind to the Process.

##### run

Run the process – run children processes, then run port and
init commands defined in config.
Also run all model observers created by [observe](#observe)

##### destroy

Destroy the process with unbinding from the model and cleaning
up all the parts of the process (stop ports, computed fields).
`__proc` field will be removed from the model object and all
children objects.

**Parameters**

-   `deep` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** If true then all children blocks will be destroyed.
                             By default, if not provided then considered as true.

##### exec

Exec a command in scope of the Process instance.
It will use binded model and logic object to run the
command. The command could be function (command factory)
or object ([Command](#command) instance).

A command origin function could return three types of things:

-   Another [Command](#command)/command factory or an array of commands
    (an element of the array also could be another array with commands
    or null/undefined/false). All commands will be execute in provided order.
-   An instance of [TaskMeta](#taskmeta) (which is usually created by [task](#task)
    helper function). The returned task will be started and do not block
    execution of next commands in the stack.
-   A plain object which is a model update object. The object will be merged
    with current model.

If command is undefined or `Process` instance not binded
to any model it will do nothing.

**Parameters**

-   `cmd` **([Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) \| [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object))** Command factory or Command instance

**Examples**

```javascript
class MyLogic {
  \@cmd BatchCommand() {
    return [
      1 > 2 && this.SomeCoomand,
      this.AnotheCommand(123),
      2 > 1 && [
        this.AndSomeOtherCommand,
        this.FinalCommand()
      ]
    ];
  }
  \@cmd TaskCommand() {
    return task(Tasks.SomeTask)
      .success(this.SuccessCommand)
      .fail(this.FailCommand)
  }
  \@cmd ModelUpdateCommand() {
    if (Math.random() > 0.6) {
      return { field: Date.now() };
    }
  }
}
```

##### finished

Returns a promise which will be resolved when all async
tasks and related handlers in the process and all children
processes will be finished.

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** 

#### Command

Class which declares a command that will be executed in the
future by some [Process#exec](#processexec). It contains a function that will be
executed, arguments that should be passed to the function
and command name.

The command also keep a context that should be used to execute
a function. Usually this context is some logic instance. You
can bind a context to the command using [Command#bind](#commandbind) function.

The command instance is immutable, so any function that
makes some change in the command will produce a new command
instead of changing the original one.

**Parameters**

-   `func` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** 
-   `args` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>** 
-   `name` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 

**Properties**

-   `func` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** An origin function that should be executed
-   `args` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>** A set of arguments that should be used
                                 to execute the fucntion.

##### exec

Execute a function stored in the command instance. It passes
stored arguments to the function and call it in stored context.
Returns the value that was returned form the function.

Returns **any** 

##### clone

Clone instance of the command

Returns **[Command](#command)** 

##### is

Check is the command equal to some other command or have
a reference to the same origin function. Optionally you can also
check that the command binded to some concrete model (using
the second argument).

You can use many different formats to define the command to check:

-   Just a string, which should be constructed like
    `Logic Class Name + Function Name`
-   Command object or command factory that you can get from prorotype
    of some logic class.
-   Binded command object or command factory that you can get from
    concrete model using [logicOf](#logicof) function

**Parameters**

-   `cmd` **([Command](#command) \| [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Command object or command factory or command name
-   `childModel` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Model object that should be binded to the command (optional)

**Examples**

```javascript
class ChildLogic {
  \@cmd SomeCommand() {}
}
class MyLogic {
  hubAfter(cmd) {
    if (cmd.is('ChildLogic.SomeCommand')) {
      // by command name
    }
    if (cmd.is(ChildLogic.prorotype.SomeCommand)) {
      // by command factory
    }
    if (cmd.is(logicOf(this.model.child).SomeCommand)) {
      // by binded to a concrete model command factory (commands
      // binded for other models will be ignored)
    }
    if (cmd.is(ChildLogic.prorotype.SomeCommand, this.model.child)) {
      // by command factory and concrete child model (commands
      // binded for other models will be ignored)
    }
  }
}
```

Returns **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returns `true` if the command have same name, or same origin function
                                and binded to same model (if second argument provided)

##### appendArgs

Creates a new Command instance (clone the command) and append
given list of arguments to the current list of arguments.
Returns a new Command with new list of arguments.

**Parameters**

-   `args` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>** List of arguments that will be appened
                               to tne new Command

Returns **[Command](#command)** New command with appended arguments

##### bind

Creates a new Command instance and set given logic instance in it.
Also update command name by name of the origin function and name
of the logic class.

**Parameters**

-   `logic` **[LogicBase](#logicbase)** A logic instance that should be binded to a command

Returns **[Command](#command)** New command binded to given logic instance

#### TaskMeta

Class for declaring an async task. An instance of this object returned
from [taks](taks) function.

A task function is a function that could return a Promise. The resolved value
will be passed to a success command handler, the rejected command will be passed
to a fail command handler.

If task function do not return a Promise, then the returned value passed to a
success command, and if the function throw an error then the error passed to
a fail command.

The task function receive at least one argument – an object with `model`, `shared`
and `meta`. All the next arguments will be given from a command that returned a task,
if it is not overrided by [TaskMeta#args](#taskmetaargs)

By default a task is single-threaded. It means that every call to a task will cancel
previously running task if it is running. You can make the task to be multi-threaded
by [TaskMeta#multithread](#taskmetamultithread), so every call to a task won't cancel the running one.

In a context of the task function defined special `call` function. This function should
be used to invoke sub-tasks. It is important to use `call` to run sub-tasks because
`call` create a cancellation point of the task – if the task cancelled, then nothing
will be executed after currently running `call` sub-task.

`call` returns an object with `result` and `error` fields. If `error` field is not
empty, then something weird happened in the sub-task. `call` internally have a try/catch,
so it is not necessary to wrap it with try/catch, just check the `error` field in the
returned object and if it is not empty – handle it somehow (throw it, or do any custom
error handling)

Also in a context of the task defined a `notify` function. It is a function that execute
notify command if it is defined. The command executed with the same arguments as passed
to `notify` function. You can use it to incrementally update a model while the long
task is executing, to show some progress for the user.

**Parameters**

-   `taskFn` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** 
-   `executor` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** 

**Examples**

```javascript
async function SubTask(a, b, c) {
  this.notify(a + b + c);
  await this.call(delay, 100);
  return (a / b * c);
}
async function RootTask({ model }) {
  const { result, error } = await this.call(SubTask, 1, 0, 3);
  if (error) {
    throw new Error('Something weird happened in subtask')
  }
  return result + 10;
}
```

```javascript
class MyLogic {
  \@cmd AsyncCommand() {
    return task(Tasks.RootTask)
      .success(this.SuccessCommand)
      .fail(this.FailCommand)
      .notify(this.NotifyCommand)
  }
}
```

##### notify

Set a notify handler command. This command executed by call of `this.notify`
inside a task with the same arguments as passed to `this.notify`

**Parameters**

-   `cmd` **[Command](#command)** 

Returns **[TaskMeta](#taskmeta)** 

##### success

Set a success handler command. Will be executed with a value returned
from the task, or if the task returned a Promise – with resovled value.

**Parameters**

-   `cmd` **[Command](#command)** 

Returns **[TaskMeta](#taskmeta)** 

##### fail

Set a fail handler command. Will be executed with error throwed in the task,
or if the task returned a Promise – with rejected value.

**Parameters**

-   `cmd` **[Command](#command)** 

Returns **[TaskMeta](#taskmeta)** 

##### multithread

Define the task to be "multi-thread", so every call
will run in parallel with other calls of the same task
in scope of one process (model).

**Parameters**

-   `val` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** 

Returns **[TaskMeta](#taskmeta)** 

##### engine

Set task executor function. The executor function should return an object
that should have at least two fields: `exec` and `cancel` functions.
`exec` should return a promise which should be resolved or rejected
with an object `{ result, error }`. A `cancel` function should stop
the task execution.

**Parameters**

-   `engine` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that returns
                               `{ exec: Function, cancel: Function }` object

Returns **[TaskMeta](#taskmeta)** 

##### args

Override arguments which will be passed to the task
starting from second argument. By default a task will receive
the same set of arguments as a task command. If this function invoked,
then the task will receive given arguments instead of command arguments.

**Parameters**

-   `args` **...any** 

Returns **[TaskMeta](#taskmeta)** 

#### DefaultLogger

A class which defins a logger for tracking command execution process.
The default implmenetation just defines all possible logger
methods (log points) and print errors to the console.
Extend this class to define your own logging functionality
(like logging errors with Setnry or Loggly)

**Examples**

```javascript
// ./index.js
import { DefaultLogger, run } from 'mangojuice-core';
import MainBlock from './blocks/MainBlock';

// Implement custom logger
class SetnryLogger extends DefaultLogger {
  onCatchError(error, cmd) {
    Raven.catchException(error);
  }
}

// Pass instance of the Logger to `run` options object.
run(MainBlock, { logger: new SetnryLogger() });
```

##### onStartExec

This method invoked right before anything else - as the first thing
in [Process#exec](#processexec). Even before any [LogicBase#hubBefore](#logicbasehubbefore).

**Parameters**

-   `cmd` **[Command](#command)** Command that just started execution process

##### onStartHandling

Invoked right before command will go through all [LogicBase#hubBefore](#logicbasehubbefore) or [LogicBase#hubAfter](#logicbasehubafter)
up in the blocks tree. The second argument indicates is it called for [LogicBase#hubBefore](#logicbasehubbefore)
or for [LogicBase#hubAfter](#logicbasehubafter).

**Parameters**

-   `cmd` **[Command](#command)** Command that is going to go through hubs in parent blocks
-   `isAfter` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** If true then the command is going through "after" hubs, "before" otherwise

##### onEndHandling

Invoked when the command went through all hubs and when all sync commands
returned from hubs was executed.

**Parameters**

-   `cmd` **[Command](#command)** Command that went through all hubs
-   `isAfter` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** If true then the command going through "after" hubs, "before" otherwise

##### onExecuted

Invoked when the command function executed and the return of the function processed –
all returned commands executed, all async tasks started, the model updated.
But it invoked before the command go through "after" hubs.

**Parameters**

-   `cmd` **[Command](#command)** Command that was exectued and the return processed
-   `result` **any** Returned object from the command's function

##### onEndExec

Invoked right after the command go throught "after" hubs. It is the final
stage of command execution.

**Parameters**

-   `cmd` **[Command](#command)** Command that was fully executed and handled by parent blocks

##### onCatchError

Invoked if any uncaught error happened while execution of the command
or anywhere else in the logic, like in [LogicBase#port](#logicbaseport) or in [LogicBase#computed](#logicbasecomputed).
By default print the error using `console.error`.

**Parameters**

-   `error` **[Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)** The error instance
-   `cmd` **[Command](#command)?** Command that was executing while the error happened

#### ComputedField

Class for declaring computed field with model dependencies.
Given array shuold contain models, binded to some
logec. They will be passed to compute function in the same order.
Also they will be used to track changed and re-compute.

The class is immutable, so any call to any method will create
a new instance of `ComputedField` and the old one won't be touched.

**Parameters**

-   `deps` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)>** 

**Properties**

-   `deps` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)>** An array of models with binded logic
                                    (attached some [Process](#process))
-   `computeFn` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A compute function that will be used
                                    to compute value of the computed field.

##### compute

Creates a new instance of the field and set compute function in it.

**Parameters**

-   `func` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A compute function that should return a value that
                             will be used as a value for some computed field in
                             a model. This function will be invoked with all
                             dependency models as arguments

**Examples**

```javascript
// A way to override computed field of some base logic class
// (thanks to immutability of `ComputedField`)
class MyLogic extends SomeOtherLogic {
  computed() {
    const oldComputed = super.computed();
    return {
      ...oldComputed,

      // Override `oldField` compute function with saved dependencies
      // and use overrided compute function inside new compute function
      oldField: oldComputed.compute((...deps) => {
        return 1 > 0 || oldComputed.oldField.computeFn(...deps);
      })
    };
  }
}
```

Returns **[ComputedField](#computedfield)** New instance of the ComputedField with `computeFn`
                         set to given function.

#### Mounter

To use [mount](#mount) function you need to implement a Mounter interface
which should have `mount` and `unmount` functions. It is up to the developer
how these functions will be implemented and what view library they will use.

There is a rule that mounter and view library should follow: view of
a model should be updated only when the model updated and the update
shouldn't touch views of children models (children views shouldn't be updated
because their models is not changed).

React perfectly fits for this rule. By implementing `shuoldComponentUpdate`
you can control when the component should be updated and when shouldn't. In this
case this function should always return `false` and componenent should be
updated using `forceUpdate` only when the model is updated (using [observe](#observe)).

**Properties**

-   `mount` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that should expect two arguments: model object with
                                  attached [Process](#process) instance and [Block#View](Block#View).
                                  It should render the model using given View (somehow).
-   `unmount` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that shuold unmount mounted view from DOM.

**Examples**

```javascript
// Minimal react mounter which follow the rules
class ViewWrapper extends React.Component {
  componentDidMount() {
    const { model } = this.props;
    this.stopObserver = observe(model, () => this.forceUpdate())
  }
  componentWillUnmount() {
    this.stopObserver();
  }
  shouldComponentUpdate() {
    return false;
  }
  render() {
    const { View, model } = this.props;
    const Logic = logicOf(model);
    return <View model={model} Logic={Logic} />
  }
}
class ReactMounter {
  mount(model, View) {
    return React.render(
      <ViewWrapper View={View} model={model} />,
      document.querySelector('#container')
    );
  }
  unmount() {
    return React.unmountComponentAtNode(
      document.querySelector('#container')
    );
  }
}
```

#### defineCommand

Provides a way to define a command in the prototype without
usign a decorator. You should give a prototype of the logic class,
name of the function which should be converted to a command factory
and the decorator function (optional).

If the decorator function is not provided, then [cmd](#cmd) will be used
by default.

**Parameters**

-   `proto` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Logic class prototype
-   `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Method name that you want to convert to a command factory
-   `decorator` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** Optional decorator function

**Examples**

```javascript
class MyLogic {
  SomeCommand() {
    return { field: this.model.field + 1 };
  }
  // throttle 100
  ThrottledCommand() {
    return this.SomeCommand();
  }
}

defineCommand(MyLogic.prototype, 'SomeCommand');
defineCommand(MyLogic.prototype, 'ThrottledCommand', cmd({ throttle: 100 }));
```

#### ensureCommand

Returns a [Command](#command) instance or throw an error if given
argument can't be used to create a [Command](#command) (is not a Command
or command factory).

**Parameters**

-   `cmd` **([Command](#command) \| [function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function))** [Command](#command) instance or command factory. When
                                     command factory then it will be invoked with
                                     no arguments to create a command

**Examples**

```javascript
class MyLogic() {
  \@cmd SomeCommand() {
    // do something
  }
}

const logic = new MyLogic();
ensureCommand(logic.SomeCommand) // returns Command instance
// equals to...
logic.SomeCommand()
```

Returns **[Command](#command)** 

#### decorateLogic

By given logic class go through prototypes chain and
decorate all cmd functions. Use it if you can't use decorators
in your project

It determine that the function should be converted to a command
factory (decorated by [cmd](#cmd)) by its name. If the function
starts with uppercase letter or underscore+upper-letter, then it
is considered as a command.

**Parameters**

-   `LogicClass` **[LogicBase](#logicbase)** Logic class that you want to decorate
-   `deep` **bool** If true then it will go though prototypes chain and
                        decorate every prototype in the chain.

**Examples**

```javascript
class MyLogic {
  SomeCommand() {
  }
  _SomePrivateCommand() {
  }
  notACommand() {
    return 123;
  }
}

// `SomeCommand` and `_SomePrivateCommand` will be decorated with `cmd`
// (the prorotype will be changed in-place). `notACommand` won't
// be decorated.
decorateLogic(MyLogic);

const logic = new MyLogic();
logic.SomeCommand() // returns Command instance
logic._SomePrivateCommand() // returns Command instance
logic.notACommand() // returns 123
```

#### handleBefore

Function adds a handler to the [Process](#process) attached to a given
model that will be invoked before every command running for this
model. The handler won't be invoked for commands from children
models of given model.

Returns a function that removes the handler from the Process
(stop handling)

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object with attached [Process](#process)
-   `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that will be called before every own command

**Examples**

```javascript
import { handleBefore, run, logicOf } from 'mangojuice-core';

// Define root and child logic
class ChildLogic {
  \@cmd ChildCommand() {}
}
class MyLogic {
  children() {
    return { childModel: ChildLogic };
  }
  \@cmd RootCommand() {}
}

// Run block with empty models
const res = run({
  Logic: MyLogic,
  createModel: () => ({ childModel: {} })
});

// Adds a handler to a root model
handleBefore(res.model, (cmd) => console.log(cmd));

// Run commands on root and child models
res.proc.exec(logicOf(res.model).RootCommand);
res.proc.exec(logicOf(res.model.childModel).ChildCommand);

// In the console will be printed only `RootCommand` command object
// right before the command will be executed
```

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that stopps the handler

#### handleAfter

It is the same as [handleBefore](#handlebefore) but the handler will be invoked
**after** every own command.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object with attached [Process](#process)
-   `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that will be called after every own command

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that stopps the handler

#### handle

Alias for [handleAfter](#handleafter)

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object with attached [Process](#process)
-   `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that will be called after every own command

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that stopps the handler

#### logicOf

Returns a Logic instance attached to a given model object. The logic
instance stored in attached [Process](#process) instance, so it execute
[procOf](#procof) for the model to get a [Process](#process) instance and then
get the logic instance form a Process and return it.

If Process is not attached to the model, then an Error will be throwed.
If the second argument passed then it will also check that the logic
instance is instance of some particular class.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model with attached [Process](#process)
-   `logicClass` **Class?** Optional logic class to check that the logic
                                  instance is instance of the class

Returns **[LogicBase](#logicbase)** Returns a logic instance

#### observe

A function that adds a handler to the [Process](#process) instance attached
to a given model, that will be invoked on every command that changed
the model. Useful for tracking changes to re-render a view of the model.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model with attached [Process](#process) instance
-   `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that will be invoked after every command
                                that changed the model.
-   `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** An object with options
    -   `options.batched` **bool** If true then the handler will be invoked only when
                                        the commands stack is empty and model was changed during
                                        the stack execution. Useful to reduce amount of not necessary
                                        view re-renderings.

**Examples**

```javascript
import { run, cmd, observe, logicOf } from 'mangojuice-core';

class MyLogic {
  \@cmd MultipleUpdates() {
    return [
      this.UpdateOne,
      this.UpdateTwo
    ];
  }
  \@cmd UpdateOne() {
    return { one: this.model.one + 1 };
  }
  \@cmd UpdateTwo() {
    return { two: this.model.two + 1 };
  }
}

const res = run({
  Logic: MyLogic,
  createModel: () => ({ one: 1, two: 1 })
});

observe(res.model, () => console.log('not-batched'));
observe(res.model, () => console.log('batched'), { batched: true });

res.proc.exec(logicOf(res.model).MultipleUpdates);

// `not-batched` will be printed two times
// `batched` will be printed only once
```

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** 

#### procOf

Get a [Process](#process) instance attached to the given model object.
Internally it get a `__proc` field from the given model and returns it.

If given model do not have attached Process, then an Error will be throwed,
but only if the second argument is not true, which ignores the error.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model with attached [Process](#process)
-   `ignoreError` **bool** If true then no error will be throwed if Process
                               is not attached to the model

Returns **[Process](#process)** An instance of [Process](#process) attached to the model

#### bind

This function do the following:

-   Creates a model object using [Block#createModel](Block#createModel). It is invoked without
    arguments.
-   Create a [Process](#process) instance with logic from [Block#Logic](Block#Logic)
-   Call [Process#bind](#processbind) with created model

Returns an object with created process instance, model object and given block.
Usefull when you want to prepare the block to run but you want to run it manually.

**Parameters**

-   `block` **[Block](#block)** A [Block](#block) object
-   `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Options object that could change [Process](#process) behaviour (optional, default `{}`)
    -   `opts.logger` **[DefaultLogger](#defaultlogger)?** A custom logger instance that will be used in the
                                               Process to track commands execution. By default
                                               [DefaultLogger](#defaultlogger) will be used.
    -   `opts.shared` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** An object that will be available in any logic in the
                                          tree as `this.shared`. Could be anything you want, but
                                          you will get more benifites if you will pass model object
                                          with attached Process as shared object to be able to make
                                          computed fields with depending of shared model.
    -   `opts.args` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>?** An array of arguments that will be passed to [LogicBase#config](#logicbaseconfig)
                                               of the logic.
    -   `opts.Process` **[Process](#process)?** A class that will be used instead of [Process](#process). By default
                                          general [Process](#process) is used, but you can customize it for your
                                          specific needs and pass here. Then every other process in the tree
                                          will be an instance of this custom [Process](#process) implementation

Returns **{proc: [Process](#process), model: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), block: [Block](#block)}** An object with [Process](#process) instance, model object and block that was passed to
   the function

#### hydrate

This function replace a `createModel` function in given block
with new function that just returns a given model. It is useful
when you have some old model and just want to run everytihing with
it (for example for server rendering, or hot module replacement)

**Parameters**

-   `block` **[Block](#block)** An original block
-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object that you want to use

**Examples**

```javascript
// Hot module replacement example
import MyBlock from './MyBlock';
import { hydrate, run } from 'mangojuice-core';

// Run initial block
let res = run(MyBlock);

// When block changed destroy the old process, hydrate a new
// block with existing model and run hydrated new block again
module.hot.accept(['./MyBlock'], () => {
  res.proc.destroy();
  const newBlock = hydrate(require('./MyBlock'), res.model);
  res = run(newBlock);
});
```

Returns **[Block](#block)** A new block with replaced `createModel` function
                 which just returns a model that you passed as
                 second argument.

#### delay

A helper function for delaying execution. Returns a Promise
which will be resolved in given amount of milliseconds. You can
use it in [task](#task) to implement some delay in execution, for
debouncing for example.

**Parameters**

-   `ms` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** An amount of milliseconds to wait

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** A promise that resolved after given amount of milliseconds

## Basic

The most common APIs that you will work with most of the time

### Block

Block is a top level component in MangoJuice which consists of three parts:

-   Model factory function `createModel` which should return a plain object.
    The main requirement for this function is that it should be able to return
    some model with zero arguments. But it can also accept some arguments
    as well.
-   A logic class which implements [LogicBase](#logicbase) interface
-   A View function which is aimed to render the model created by `createModel`

The View part is optional and it could have different type depending on
selected View library to render a model and particular binding library.

**Properties**

-   `Logic` **[LogicBase](#logicbase)** A logic class that should be attached to the model.
-   `createModel` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that shuld return a plain object which
                                      will be an init model of the block.
-   `View` **any?** Something that some particular view library can render

**Examples**

```javascript
// You can define block in short way using an object
const MyBlock = {
  createModel: () => ({ field: 1 }),
  Logic: class MyLogic {
    \@cmd SomeCommand() {
      return { field: this.model.field + 1 };
    }
  },
  View: ({ model }) => (
    <div>{model.field}</div>
  )
};

run(MyBlock);
```

```javascript
// Or you can split it with modules (recommended)
// ./MyBlock/index.js
import Logic from './Logic';
import View from './View';
import { createModel } from './Model';
export default { View, Logic, createModel };
export { View, Logic, createModel };
export type { Model } from './Model';

// ./MyBlock/Logic.js
import type { Model } from './Model';
import { LogicBase, cmd } from 'mangojuice-core';

export default class MyLogic extends LogicBase<Model> {
  \@cmd SomeCommand() {
    return { field: this.model.field + 1 };
  }
}

// ./MyBlock/Model.js
export type Model = { field: number };
export const createModel = () => ({
  field: 1
});

// ./MyBlock/View.js
const MyBlockView = ({ model }) => (
  <div>{model.field}</div>
);
export default MyBlockView;

// ./index.js
import MyBlock from './MyBlock';
import { run } from 'mangojuice-core';

run(MyBlock);
```

### LogicBase

Basic class for every logic. It is not necessaty to inherit an actual logic
class from it, but for better type-checking it could be really usefull.

Logic class defines:

-   A set of commands that could change an associated model – methods decorated with [cmd](#cmd)
-   What fields of the model should be associated with which logic class
    (children blocks) – [LogicBase#children](#logicbasechildren) method
-   A set of computed model fields – [LogicBase#computed](#logicbasecomputed) method
-   A set of rules to handle commands from children logic – [LogicBase#hubAfter](#logicbasehubafter)
    and [LogicBase#hubBefore](#logicbasehubbefore) methods
-   A logic to handle external events – [LogicBase#port](#logicbaseport) method.

The logic class defines all the business-logic of some part of your application.
The main goal of the logic – change associated model. Check [cmd](#cmd) and [Process#exec](#processexec)
to have a better understanding how command can be defined and how it is executed.

**Properties**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object which is associated with the
                               logic class in parent logic.
-   `meta` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** An object defined in [LogicBase#config](#logicbaseconfig) method for storing
                               some internal logic state.
-   `shared` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** An object with some shared state, defined while
                               run process of the app.

**Examples**

```javascript
// ./blocks/MyBlock/Logic.js
// @flow
import type { Model } from './Model';
import ChildBlock from '../ChildBlock';
import { Command, cmd } from 'mangojuice-core';

export default class MyLogic extends LogicBase<Model> {
  children() {
    return { child: ChildBlock.Logic };
  }
  hubAfter(cmd: Command) {
    if (cmd.is(ChildBlock.Logic.prototype.SomeCommand)) {
      return this.TestCommand(123);
    }
  }
  \@cmd TestCommand(arg) {
    return { field: arg + this.model.field };
  }
}
```

#### config

A function that defines init commands and meta object of the
logic. Can accept any type and number of arguments. Config
will take arguments passed to [child](#child) function (for example
`child(MyLogic, 1, 2, 3)` defines that the `config` method of
`MyLogic` will be invoked like `config(1, 2, 3)`)

Could return an object with the fields:

-   `initCommands` which could be an array or a single Command,
    that will be executed every time when the logic instance created
    and associated with some model (when [Process#run](#processrun) invoked)
-   `meta` which could be an object with some internal state of
    the logic

**Examples**

```javascript
config(props) {
  return {
    initCommands: [ this.StartThis, this.SendThat(123) ],
    meta: { something: props.amount }
  };
}
```

#### children

This function defines what logic class should be associated
with which model field. Should return an object where a key is
a model field name, and a value is a logic class or an object
that defines logic with arguments (return from [child](#child) function)

**Examples**

```javascript
children() {
  return {
    searchForm: child(SearchForm.Logic, { timeout: 100 }),
    searchResults: SearchResults.Logic
  };
}
```

Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**

#### computed

Should return an object which defines computed fields of the model.
A key of the object is a model field, and value is a function or
computed function definition object (return from [depends](#depends) function).

Computed field is lazy, which means that it is computed on the first use
of the field and the computation result cached until the next update
of the model.

If you want to define a computed field which ueses in computation not
only fields from the own model, but maybe some values from child model,
or from shared model, then you will need to use [depends](#depends) function to
define what models used while computation to observe changes of these
models to trigger an update event of the own model (to update views).

**Examples**

```javascript
computed() {
  return {
    simple: () => this.model.a + this.model.b,
    withDeps: depends(this.model.child, this.shared).compute(() => {
      return this.model.child.a + this.shared.b + this.model.c;
    })
  };
}
```

Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**

#### port

A function to handle global event, such as browser-level events,
websocket, intervals. The main porpouse of the `port` is to subscribe
to some global events, execute appropriate commands from the logic
on the events and remove the handlers when the logic was destroyed.

**Parameters**

-   `exec` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** It is a function that execute a passed command
-   `destroyed` **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** A promise that will be resolved when the logic destroyed

**Examples**

```javascript
port(exec, destroyed) {
  const timer = setInterval(() => {
    exec(this.SecondPassed);
  }, 1000);
  destroyed.then(() => clearInterval(timer));
}
```

#### hubAfter

Hub for all commands executed in the children blocks. The only
arguments is a command object that was executed.
Could return a Command or an array of Commands that should
be executed next.
Most of the time this function will look like a `switch`,
but maybe with some additional rules for the cases. Take a look
to [Command#is](#commandis) function to have a better understanding how you
can determine that the command is exactly what you are waiting for.

**Parameters**

-   `cmd` **[Command](#command)** Command that was executed in some child logic
                           or in any child of the child and so on down to
                           the leaf of the tree.

**Examples**

```javascript
hubAfter(cmd) {
  if (cmd.is(ChildBlock.Logic.prototype.SomeCommand)) {
    return this.HandlerCommand(123);
  }
  if (cmd.is('AnotherChild.SomeAnothercommand')) {
    return [ this.HandlerCommand(321), this.AnotherHandler ];
  }
}
```

Returns **([Command](#command)? | [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Command](#command)>?)**

#### hubBefore

Same as [LogicBase#hubAfter](#logicbasehubafter), but catch commands before
it will be actually executed, so you can compare prev and next
model state for example.

**Parameters**

-   `cmd` **[Command](#command)**

Returns **([Command](#command)? | [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Command](#command)>?)**

### cmd

Decorator that converts a logic method to a command factory.
The result function (command factory function) is a function
that return a [Command](#command) instnace with the decorated function
and arguments that you will pass to a command factory function.

You can use this decorator without arguments or with an options
argument (object)

Check [Process#exec](#processexec) to see what the origin function
could return to do something. If in short, it can return:
nothing, command (or factory or array of commands), task,
model update object.

**Parameters**

-   `obj` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** If only this argument passed then it will be considered
                                   as options object which can customize command behaviour.
    -   `obj.debounce` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** If greeter than zero then an exeuction
                                       of the command will be debounced by given amount of
                                       milliseconds
    -   `obj.throttle` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** If greeter than zero then an exeuction
                                       of the command will be throttled by given amount of
                                       milliseconds
    -   `obj.noInitCall` **bool** If true then debounced/throttled execution
                                       won't start with init command call. By default
                                       debounced/throttled command will be instantly
                                       exected and only then wait for a chance to execute
                                       again. With `noInitCall=true` there is no instant init
                                       command call.
    -   `obj.internal` **bool** Make the command invisible for parent [LogicBase#hubBefore](#logicbasehubbefore)
                                       and [LogicBase#hubAfter](#logicbasehubafter). Use it for commands that shouldn't
                                       be handled by hubs to increse performance.
    -   `obj.name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** By default name of the command taken from origin function. With this
                                       option you can override the name with any other value.
-   `methodName`
-   `descr`

**Examples**

```javascript
class RegularLogic {
  \@cmd RegularCommand() {
    // do something
  }
}
```

```javascript
class RegularLogic {
  \@cmd({ debounce: 300 })
  DebouncedCommand() {
    // if you will call this command 3 times every
    // 100ms then it will be executed 2 times,
    // first right when you call it for a first time,
    // and second in 600ms.
  }
}
```

```javascript
class RegularLogic {
  \@cmd({ throttle: 300 })
  ThrottledCommand() {
    // if you will call this command 3 times every
    // 100ms then it will be executed 2 times,
    // first right when you call it for a first time,
    // and second in 300ms.
  }
}
```

```javascript
class RegularLogic {
  \@cmd({ throttle: 300, noInitCall: true })
  ThrottledCommand() {
    // if you will call this command 3 times every
    // 100ms then it will be executed 1 time in 300ms.
  }
}
```

```javascript
class RegularLogic {
  \@cmd({ internal: true })
  _InternalCommand() {
    // this command can't be caught in `hubBefore` or `hubAfter`
    // in parent logics. Use it carefully.
  }
}
```

Returns **([Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) \| [object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object))** Command factory function (if all three arguemnts passed)
                               or a decorator function with binded options object
                               (that you pass as a first argument)

### run

Run given block. It is a short-hand function for running [bind](#bind)
and then running a Process by [Process#run](#processrun).
Also it returns an additional `finished` Promise which is resolved
when all async tasks finished and all handler commands executed.

**Parameters**

-   `block` **[Block](#block)** A block that you wan to run
-   `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Same options as in [bind](#bind) (optional, default `{}`)

Returns **{proc: [Process](#process), model: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), block: [Block](#block), finished: [Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)}** An object
                 which is almost the same as returned from [bind](#bind), but with
                 additional `finished` field, which is a Promise that will be resolved
                 when all blocks will execute all commands and all async tasks will be
                 finished.

### mount

Mount running block. As third and next arguments you can pass other running
blocks which will be stopped with the main running block (useful for HMR).

**Parameters**

-   `mounter` **[Mounter](#mounter)** An implementation of [Mounter](#mounter) interface
-   `runRes` **{proc: [Process](#process), block: [Block](#block), model: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)}** An object that returned
                     from [run](#run) function.
-   `otherBlocks` **...any**

**Examples**

```javascript
const MyBlock = {
  createModel: () => ({ field: 1 }),
  Logic: class MyLogic {
    \@cmd SomeCommand() {
      return { field: this.model.field + 1 };
    }
  },
  View: ({ model }) => (
    <div>{model.field}</div>
  )
};

mount(new ReactMounter(), run(MyBlock));
```

Returns **{view: any, stop: [Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)}** An object with the result form [Mounter#mount](Mounter#mount)
                 function (in `view` field) and stop function which destroy the process and
                 unmount a view using [Mounter#unmount](Mounter#unmount)

### task

Creates a [TaskMeta](#taskmeta) object that could be returned from
async task command. It describes the task that should be executed.

For more information what the **Task** is and how it should be implemented
take a look to [TaskMeta](#taskmeta).

**Parameters**

-   `taskFn` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that could return a Promise

**Properties**

-   `CANCEL` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** A symbol that you can use to make a promise "cancellable"

Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**

### cancel

This function should be used to cancel async [task](#task) execution.
Also it can cancel the debounced/throttled command.

-   In case with task, if task was executing while you call a cancel command,
    the task will be cancelled (execution stopped). Otherwise nothing will happen.
-   In case with debounced/throttled command, if the command scheduled to be executed
    then the schedule timer will be cleared and the command won't be executed.
    If the command is not scheduled then nothing happens.

To use it just pass a command or command factory as a first argument
and return it from some other command.

**Parameters**

-   `cmd` **([Command](#command) \| [function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function))** Command or command factory that you wan to cancel. Could
                                    be a command that returns [task](#task) or debounced/throttled
                                    command

**Examples**

```javascript
class SomeLogic {
  \@cmd CancelSomethingCommand() {
    return [
      cancel(this.TaskCommand),
      cancel(this.DebounceCommand)
    ];
  }
  \@cmd TaskCommand() {
    return task(Tasks.SomeTask);
  }
  \@cmd({ debounce: 300 })
  DebounceCommand() {
    // do something
  }
}
```

Returns **[Command](#command)** Returns a new command that will cancel the execution of the command
                  passed as an argument.

### child

Creates an object which describes child logic which will be attached
to some model field. Should be used in [LogicBase#children](#logicbasechildren) to
define a logic that should be instantiated with some arguments passed
to [LogicBase#config](#logicbaseconfig).

**Parameters**

-   `logicClass` **[LogicBase](#logicbase)** Class that imlements [LogicBase](#logicbase) interface
-   `args` **...any**

**Examples**

```javascript
class ChildLogic {
  config(amount) {
    return { meta: { amount } };
  }
}
class RootLogic {
  children() {
    return {
      modelField: child(ChildLogic, 10)
      // `config` of `ChildLogic` will be invoked with
      // `10` as a first argument
    }
  }
}
```

Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object that contains a logic class and an arguments array that
                 should be used to invoke `config` method of provided logic class.

### depends

Function that helps to describe a computed field with external
model dependncies. Should be used in [LogicBase#computed](#logicbasecomputed).
It creates an instance of [ComputedField](#computedfield) with dependencies
passed as arguments.

A compute field with external dependencies is a field that should
be updated (re-computed) not only when the own model udpated, but
also when depdendency models updated.

**Parameters**

-   `deps` **...deps** A list of models with attached logic

**Examples**

```javascript
class ChildLogic {
  // some logic
}
class MyLogic {
  children() {
    return { childModel: ChildLogic };
  }
  computed() {
    return {
      // depends on `childModel`
      computedField: depends(this.model.childModel).compute(() => {
        return this.model.a + this.model.childModel.b;
      }),

      // depends on `shared` model
      computeWithShared: depends(this.shared).compute(() => {
        return this.model.b + this.shared.someField;
      })
    }
  }
}
```

Returns **[ComputedField](#computedfield)**

## Extras

Other pieces of MangoJuice

### Process

The main class of MangoJuice that ties model, logic and view together.

It works in the following way:

-   You create a model for your app (object) using `createModel` of
    the root block. The result is a plain object.
-   Then you need to create an instance of Process and pass logic class
    in the options object.
-   Then you `bind` the Process instance to the model object you created on step one.
    "To bind Process to a model" means that in the model will be created a hidden
    field `__proc` with a reference to the Process instance.
-   After that you can `run` the Process, which will execute init commands, port.

`bind` and `run` also look at the object returned from [LogicBase#children](#logicbasechildren)
and create/run Process instances for children models.

Most of the time you do not need to care about all of these and just use
[run](#run) and [mount](#mount). These small functions do everything described
above for you.

**Examples**

```javascript
import { Process, logicOf } from 'mangojuice-core';

const ExampleBlock = {
  createModel() {
    return { a: 10 };
  },
  Logic: class Example {
    \@cmd Increment(amount = 1) {
      return { a: this.model.a + amount };
    }
  }
};

const model = ExampleBlock.createModel();
const proc = new Process({ logic: ExampleBlock.Logic });
proc.bind(model);
proc.run();
proc.exec(logicOf(model).Increment(23));
```

#### bind

Bind the process instance to a given model, which means that hidden
`__proc` field will be created in the model with a reference to the
Process instance.

Also bind all children models – go through children definition returned
by [LogicBase#children](#logicbasechildren), create Process for each child and bind
it to an appropreat child model object.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object that you want to bind to the Process.

#### run

Run the process – run children processes, then run port and
init commands defined in config.
Also run all model observers created by [observe](#observe)

#### destroy

Destroy the process with unbinding from the model and cleaning
up all the parts of the process (stop ports, computed fields).
`__proc` field will be removed from the model object and all
children objects.

**Parameters**

-   `deep` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** If true then all children blocks will be destroyed.
                             By default, if not provided then considered as true.

#### exec

Exec a command in scope of the Process instance.
It will use binded model and logic object to run the
command. The command could be function (command factory)
or object ([Command](#command) instance).

A command origin function could return three types of things:

-   Another [Command](#command)/command factory or an array of commands
    (an element of the array also could be another array with commands
    or null/undefined/false). All commands will be execute in provided order.
-   An instance of [TaskMeta](#taskmeta) (which is usually created by [task](#task)
    helper function). The returned task will be started and do not block
    execution of next commands in the stack.
-   A plain object which is a model update object. The object will be merged
    with current model.

If command is undefined or `Process` instance not binded
to any model it will do nothing.

**Parameters**

-   `cmd` **([Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) \| [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object))** Command factory or Command instance

**Examples**

```javascript
class MyLogic {
  \@cmd BatchCommand() {
    return [
      1 > 2 && this.SomeCoomand,
      this.AnotheCommand(123),
      2 > 1 && [
        this.AndSomeOtherCommand,
        this.FinalCommand()
      ]
    ];
  }
  \@cmd TaskCommand() {
    return task(Tasks.SomeTask)
      .success(this.SuccessCommand)
      .fail(this.FailCommand)
  }
  \@cmd ModelUpdateCommand() {
    if (Math.random() > 0.6) {
      return { field: Date.now() };
    }
  }
}
```

#### finished

Returns a promise which will be resolved when all async
tasks and related handlers in the process and all children
processes will be finished.

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)**

### Command

Class which declares a command that will be executed in the
future by some [Process#exec](#processexec). It contains a function that will be
executed, arguments that should be passed to the function
and command name.

The command also keep a context that should be used to execute
a function. Usually this context is some logic instance. You
can bind a context to the command using [Command#bind](#commandbind) function.

The command instance is immutable, so any function that
makes some change in the command will produce a new command
instead of changing the original one.

**Parameters**

-   `func` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
-   `args` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>**
-   `name` **[String](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**

**Properties**

-   `func` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** An origin function that should be executed
-   `args` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>** A set of arguments that should be used
                                 to execute the fucntion.

#### exec

Execute a function stored in the command instance. It passes
stored arguments to the function and call it in stored context.
Returns the value that was returned form the function.

Returns **any**

#### clone

Clone instance of the command

Returns **[Command](#command)**

#### is

Check is the command equal to some other command or have
a reference to the same origin function. Optionally you can also
check that the command binded to some concrete model (using
the second argument).

You can use many different formats to define the command to check:

-   Just a string, which should be constructed like
    `Logic Class Name + Function Name`
-   Command object or command factory that you can get from prorotype
    of some logic class.
-   Binded command object or command factory that you can get from
    concrete model using [logicOf](#logicof) function

**Parameters**

-   `cmd` **([Command](#command) \| [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))** Command object or command factory or command name
-   `childModel` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Model object that should be binded to the command (optional)

**Examples**

```javascript
class ChildLogic {
  \@cmd SomeCommand() {}
}
class MyLogic {
  hubAfter(cmd) {
    if (cmd.is('ChildLogic.SomeCommand')) {
      // by command name
    }
    if (cmd.is(ChildLogic.prorotype.SomeCommand)) {
      // by command factory
    }
    if (cmd.is(logicOf(this.model.child).SomeCommand)) {
      // by binded to a concrete model command factory (commands
      // binded for other models will be ignored)
    }
    if (cmd.is(ChildLogic.prorotype.SomeCommand, this.model.child)) {
      // by command factory and concrete child model (commands
      // binded for other models will be ignored)
    }
  }
}
```

Returns **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Returns `true` if the command have same name, or same origin function
                                and binded to same model (if second argument provided)

#### appendArgs

Creates a new Command instance (clone the command) and append
given list of arguments to the current list of arguments.
Returns a new Command with new list of arguments.

**Parameters**

-   `args` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>** List of arguments that will be appened
                               to tne new Command

Returns **[Command](#command)** New command with appended arguments

#### bind

Creates a new Command instance and set given logic instance in it.
Also update command name by name of the origin function and name
of the logic class.

**Parameters**

-   `logic` **[LogicBase](#logicbase)** A logic instance that should be binded to a command

Returns **[Command](#command)** New command binded to given logic instance

### TaskMeta

Class for declaring an async task. An instance of this object returned
from [taks](taks) function.

A task function is a function that could return a Promise. The resolved value
will be passed to a success command handler, the rejected command will be passed
to a fail command handler.

If task function do not return a Promise, then the returned value passed to a
success command, and if the function throw an error then the error passed to
a fail command.

The task function receive at least one argument – an object with `model`, `shared`
and `meta`. All the next arguments will be given from a command that returned a task,
if it is not overrided by [TaskMeta#args](#taskmetaargs)

By default a task is single-threaded. It means that every call to a task will cancel
previously running task if it is running. You can make the task to be multi-threaded
by [TaskMeta#multithread](#taskmetamultithread), so every call to a task won't cancel the running one.

In a context of the task function defined special `call` function. This function should
be used to invoke sub-tasks. It is important to use `call` to run sub-tasks because
`call` create a cancellation point of the task – if the task cancelled, then nothing
will be executed after currently running `call` sub-task.

`call` returns an object with `result` and `error` fields. If `error` field is not
empty, then something weird happened in the sub-task. `call` internally have a try/catch,
so it is not necessary to wrap it with try/catch, just check the `error` field in the
returned object and if it is not empty – handle it somehow (throw it, or do any custom
error handling)

Also in a context of the task defined a `notify` function. It is a function that execute
notify command if it is defined. The command executed with the same arguments as passed
to `notify` function. You can use it to incrementally update a model while the long
task is executing, to show some progress for the user.

**Parameters**

-   `taskFn` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**
-   `executor` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**

**Examples**

```javascript
async function SubTask(a, b, c) {
  this.notify(a + b + c);
  await this.call(delay, 100);
  return (a / b * c);
}
async function RootTask({ model }) {
  const { result, error } = await this.call(SubTask, 1, 0, 3);
  if (error) {
    throw new Error('Something weird happened in subtask')
  }
  return result + 10;
}
```

```javascript
class MyLogic {
  \@cmd AsyncCommand() {
    return task(Tasks.RootTask)
      .success(this.SuccessCommand)
      .fail(this.FailCommand)
      .notify(this.NotifyCommand)
  }
}
```

#### notify

Set a notify handler command. This command executed by call of `this.notify`
inside a task with the same arguments as passed to `this.notify`

**Parameters**

-   `cmd` **[Command](#command)**

Returns **[TaskMeta](#taskmeta)**

#### success

Set a success handler command. Will be executed with a value returned
from the task, or if the task returned a Promise – with resovled value.

**Parameters**

-   `cmd` **[Command](#command)**

Returns **[TaskMeta](#taskmeta)**

#### fail

Set a fail handler command. Will be executed with error throwed in the task,
or if the task returned a Promise – with rejected value.

**Parameters**

-   `cmd` **[Command](#command)**

Returns **[TaskMeta](#taskmeta)**

#### multithread

Define the task to be "multi-thread", so every call
will run in parallel with other calls of the same task
in scope of one process (model).

**Parameters**

-   `val` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**

Returns **[TaskMeta](#taskmeta)**

#### engine

Set task executor function. The executor function should return an object
that should have at least two fields: `exec` and `cancel` functions.
`exec` should return a promise which should be resolved or rejected
with an object `{ result, error }`. A `cancel` function should stop
the task execution.

**Parameters**

-   `engine` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that returns
                               `{ exec: Function, cancel: Function }` object

Returns **[TaskMeta](#taskmeta)**

#### args

Override arguments which will be passed to the task
starting from second argument. By default a task will receive
the same set of arguments as a task command. If this function invoked,
then the task will receive given arguments instead of command arguments.

**Parameters**

-   `args` **...any**

Returns **[TaskMeta](#taskmeta)**

### DefaultLogger

A class which defins a logger for tracking command execution process.
The default implmenetation just defines all possible logger
methods (log points) and print errors to the console.
Extend this class to define your own logging functionality
(like logging errors with Setnry or Loggly)

**Examples**

```javascript
// ./index.js
import { DefaultLogger, run } from 'mangojuice-core';
import MainBlock from './blocks/MainBlock';

// Implement custom logger
class SetnryLogger extends DefaultLogger {
  onCatchError(error, cmd) {
    Raven.catchException(error);
  }
}

// Pass instance of the Logger to `run` options object.
run(MainBlock, { logger: new SetnryLogger() });
```

#### onStartExec

This method invoked right before anything else - as the first thing
in [Process#exec](#processexec). Even before any [LogicBase#hubBefore](#logicbasehubbefore).

**Parameters**

-   `cmd` **[Command](#command)** Command that just started execution process

#### onStartHandling

Invoked right before command will go through all [LogicBase#hubBefore](#logicbasehubbefore) or [LogicBase#hubAfter](#logicbasehubafter)
up in the blocks tree. The second argument indicates is it called for [LogicBase#hubBefore](#logicbasehubbefore)
or for [LogicBase#hubAfter](#logicbasehubafter).

**Parameters**

-   `cmd` **[Command](#command)** Command that is going to go through hubs in parent blocks
-   `isAfter` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** If true then the command is going through "after" hubs, "before" otherwise

#### onEndHandling

Invoked when the command went through all hubs and when all sync commands
returned from hubs was executed.

**Parameters**

-   `cmd` **[Command](#command)** Command that went through all hubs
-   `isAfter` **[Boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** If true then the command going through "after" hubs, "before" otherwise

#### onExecuted

Invoked when the command function executed and the return of the function processed –
all returned commands executed, all async tasks started, the model updated.
But it invoked before the command go through "after" hubs.

**Parameters**

-   `cmd` **[Command](#command)** Command that was exectued and the return processed
-   `result` **any** Returned object from the command's function

#### onEndExec

Invoked right after the command go throught "after" hubs. It is the final
stage of command execution.

**Parameters**

-   `cmd` **[Command](#command)** Command that was fully executed and handled by parent blocks

#### onCatchError

Invoked if any uncaught error happened while execution of the command
or anywhere else in the logic, like in [LogicBase#port](#logicbaseport) or in [LogicBase#computed](#logicbasecomputed).
By default print the error using `console.error`.

**Parameters**

-   `error` **[Error](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error)** The error instance
-   `cmd` **[Command](#command)?** Command that was executing while the error happened

### ComputedField

Class for declaring computed field with model dependencies.
Given array shuold contain models, binded to some
logec. They will be passed to compute function in the same order.
Also they will be used to track changed and re-compute.

The class is immutable, so any call to any method will create
a new instance of `ComputedField` and the old one won't be touched.

**Parameters**

-   `deps` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)>**

**Properties**

-   `deps` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)>** An array of models with binded logic
                                    (attached some [Process](#process))
-   `computeFn` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A compute function that will be used
                                    to compute value of the computed field.

#### compute

Creates a new instance of the field and set compute function in it.

**Parameters**

-   `func` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A compute function that should return a value that
                             will be used as a value for some computed field in
                             a model. This function will be invoked with all
                             dependency models as arguments

**Examples**

```javascript
// A way to override computed field of some base logic class
// (thanks to immutability of `ComputedField`)
class MyLogic extends SomeOtherLogic {
  computed() {
    const oldComputed = super.computed();
    return {
      ...oldComputed,

      // Override `oldField` compute function with saved dependencies
      // and use overrided compute function inside new compute function
      oldField: oldComputed.compute((...deps) => {
        return 1 > 0 || oldComputed.oldField.computeFn(...deps);
      })
    };
  }
}
```

Returns **[ComputedField](#computedfield)** New instance of the ComputedField with `computeFn`
                         set to given function.

### Mounter

To use [mount](#mount) function you need to implement a Mounter interface
which should have `mount` and `unmount` functions. It is up to the developer
how these functions will be implemented and what view library they will use.

There is a rule that mounter and view library should follow: view of
a model should be updated only when the model updated and the update
shouldn't touch views of children models (children views shouldn't be updated
because their models is not changed).

React perfectly fits for this rule. By implementing `shuoldComponentUpdate`
you can control when the component should be updated and when shouldn't. In this
case this function should always return `false` and componenent should be
updated using `forceUpdate` only when the model is updated (using [observe](#observe)).

**Properties**

-   `mount` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that should expect two arguments: model object with
                                  attached [Process](#process) instance and [Block#View](Block#View).
                                  It should render the model using given View (somehow).
-   `unmount` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that shuold unmount mounted view from DOM.

**Examples**

```javascript
// Minimal react mounter which follow the rules
class ViewWrapper extends React.Component {
  componentDidMount() {
    const { model } = this.props;
    this.stopObserver = observe(model, () => this.forceUpdate())
  }
  componentWillUnmount() {
    this.stopObserver();
  }
  shouldComponentUpdate() {
    return false;
  }
  render() {
    const { View, model } = this.props;
    const Logic = logicOf(model);
    return <View model={model} Logic={Logic} />
  }
}
class ReactMounter {
  mount(model, View) {
    return React.render(
      <ViewWrapper View={View} model={model} />,
      document.querySelector('#container')
    );
  }
  unmount() {
    return React.unmountComponentAtNode(
      document.querySelector('#container')
    );
  }
}
```

### defineCommand

Provides a way to define a command in the prototype without
usign a decorator. You should give a prototype of the logic class,
name of the function which should be converted to a command factory
and the decorator function (optional).

If the decorator function is not provided, then [cmd](#cmd) will be used
by default.

**Parameters**

-   `proto` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** Logic class prototype
-   `name` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Method name that you want to convert to a command factory
-   `decorator` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** Optional decorator function

**Examples**

```javascript
class MyLogic {
  SomeCommand() {
    return { field: this.model.field + 1 };
  }
  // throttle 100
  ThrottledCommand() {
    return this.SomeCommand();
  }
}

defineCommand(MyLogic.prototype, 'SomeCommand');
defineCommand(MyLogic.prototype, 'ThrottledCommand', cmd({ throttle: 100 }));
```

### ensureCommand

Returns a [Command](#command) instance or throw an error if given
argument can't be used to create a [Command](#command) (is not a Command
or command factory).

**Parameters**

-   `cmd` **([Command](#command) \| [function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function))** [Command](#command) instance or command factory. When
                                     command factory then it will be invoked with
                                     no arguments to create a command

**Examples**

```javascript
class MyLogic() {
  \@cmd SomeCommand() {
    // do something
  }
}

const logic = new MyLogic();
ensureCommand(logic.SomeCommand) // returns Command instance
// equals to...
logic.SomeCommand()
```

Returns **[Command](#command)**

### decorateLogic

By given logic class go through prototypes chain and
decorate all cmd functions. Use it if you can't use decorators
in your project

It determine that the function should be converted to a command
factory (decorated by [cmd](#cmd)) by its name. If the function
starts with uppercase letter or underscore+upper-letter, then it
is considered as a command.

**Parameters**

-   `LogicClass` **[LogicBase](#logicbase)** Logic class that you want to decorate
-   `deep` **bool** If true then it will go though prototypes chain and
                        decorate every prototype in the chain.

**Examples**

```javascript
class MyLogic {
  SomeCommand() {
  }
  _SomePrivateCommand() {
  }
  notACommand() {
    return 123;
  }
}

// `SomeCommand` and `_SomePrivateCommand` will be decorated with `cmd`
// (the prorotype will be changed in-place). `notACommand` won't
// be decorated.
decorateLogic(MyLogic);

const logic = new MyLogic();
logic.SomeCommand() // returns Command instance
logic._SomePrivateCommand() // returns Command instance
logic.notACommand() // returns 123
```

### handleBefore

Function adds a handler to the [Process](#process) attached to a given
model that will be invoked before every command running for this
model. The handler won't be invoked for commands from children
models of given model.

Returns a function that removes the handler from the Process
(stop handling)

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object with attached [Process](#process)
-   `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that will be called before every own command

**Examples**

```javascript
import { handleBefore, run, logicOf } from 'mangojuice-core';

// Define root and child logic
class ChildLogic {
  \@cmd ChildCommand() {}
}
class MyLogic {
  children() {
    return { childModel: ChildLogic };
  }
  \@cmd RootCommand() {}
}

// Run block with empty models
const res = run({
  Logic: MyLogic,
  createModel: () => ({ childModel: {} })
});

// Adds a handler to a root model
handleBefore(res.model, (cmd) => console.log(cmd));

// Run commands on root and child models
res.proc.exec(logicOf(res.model).RootCommand);
res.proc.exec(logicOf(res.model.childModel).ChildCommand);

// In the console will be printed only `RootCommand` command object
// right before the command will be executed
```

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that stopps the handler

### handleAfter

It is the same as [handleBefore](#handlebefore) but the handler will be invoked
**after** every own command.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object with attached [Process](#process)
-   `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that will be called after every own command

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that stopps the handler

### handle

Alias for [handleAfter](#handleafter)

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object with attached [Process](#process)
-   `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that will be called after every own command

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that stopps the handler

### logicOf

Returns a Logic instance attached to a given model object. The logic
instance stored in attached [Process](#process) instance, so it execute
[procOf](#procof) for the model to get a [Process](#process) instance and then
get the logic instance form a Process and return it.

If Process is not attached to the model, then an Error will be throwed.
If the second argument passed then it will also check that the logic
instance is instance of some particular class.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model with attached [Process](#process)
-   `logicClass` **Class?** Optional logic class to check that the logic
                                  instance is instance of the class

Returns **[LogicBase](#logicbase)** Returns a logic instance

### observe

A function that adds a handler to the [Process](#process) instance attached
to a given model, that will be invoked on every command that changed
the model. Useful for tracking changes to re-render a view of the model.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model with attached [Process](#process) instance
-   `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** A function that will be invoked after every command
                                that changed the model.
-   `options` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** An object with options
    -   `options.batched` **bool** If true then the handler will be invoked only when
                                        the commands stack is empty and model was changed during
                                        the stack execution. Useful to reduce amount of not necessary
                                        view re-renderings.

**Examples**

```javascript
import { run, cmd, observe, logicOf } from 'mangojuice-core';

class MyLogic {
  \@cmd MultipleUpdates() {
    return [
      this.UpdateOne,
      this.UpdateTwo
    ];
  }
  \@cmd UpdateOne() {
    return { one: this.model.one + 1 };
  }
  \@cmd UpdateTwo() {
    return { two: this.model.two + 1 };
  }
}

const res = run({
  Logic: MyLogic,
  createModel: () => ({ one: 1, two: 1 })
});

observe(res.model, () => console.log('not-batched'));
observe(res.model, () => console.log('batched'), { batched: true });

res.proc.exec(logicOf(res.model).MultipleUpdates);

// `not-batched` will be printed two times
// `batched` will be printed only once
```

Returns **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)**

### procOf

Get a [Process](#process) instance attached to the given model object.
Internally it get a `__proc` field from the given model and returns it.

If given model do not have attached Process, then an Error will be throwed,
but only if the second argument is not true, which ignores the error.

**Parameters**

-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model with attached [Process](#process)
-   `ignoreError` **bool** If true then no error will be throwed if Process
                               is not attached to the model

Returns **[Process](#process)** An instance of [Process](#process) attached to the model

### bind

This function do the following:

-   Creates a model object using [Block#createModel](Block#createModel). It is invoked without
    arguments.
-   Create a [Process](#process) instance with logic from [Block#Logic](Block#Logic)
-   Call [Process#bind](#processbind) with created model

Returns an object with created process instance, model object and given block.
Usefull when you want to prepare the block to run but you want to run it manually.

**Parameters**

-   `block` **[Block](#block)** A [Block](#block) object
-   `opts` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** Options object that could change [Process](#process) behaviour (optional, default `{}`)
    -   `opts.logger` **[DefaultLogger](#defaultlogger)?** A custom logger instance that will be used in the
                                               Process to track commands execution. By default
                                               [DefaultLogger](#defaultlogger) will be used.
    -   `opts.shared` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** An object that will be available in any logic in the
                                          tree as `this.shared`. Could be anything you want, but
                                          you will get more benifites if you will pass model object
                                          with attached Process as shared object to be able to make
                                          computed fields with depending of shared model.
    -   `opts.args` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;any>?** An array of arguments that will be passed to [LogicBase#config](#logicbaseconfig)
                                               of the logic.
    -   `opts.Process` **[Process](#process)?** A class that will be used instead of [Process](#process). By default
                                          general [Process](#process) is used, but you can customize it for your
                                          specific needs and pass here. Then every other process in the tree
                                          will be an instance of this custom [Process](#process) implementation

Returns **{proc: [Process](#process), model: [Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object), block: [Block](#block)}** An object with [Process](#process) instance, model object and block that was passed to
   the function

### hydrate

This function replace a `createModel` function in given block
with new function that just returns a given model. It is useful
when you have some old model and just want to run everytihing with
it (for example for server rendering, or hot module replacement)

**Parameters**

-   `block` **[Block](#block)** An original block
-   `model` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** A model object that you want to use

**Examples**

```javascript
// Hot module replacement example
import MyBlock from './MyBlock';
import { hydrate, run } from 'mangojuice-core';

// Run initial block
let res = run(MyBlock);

// When block changed destroy the old process, hydrate a new
// block with existing model and run hydrated new block again
module.hot.accept(['./MyBlock'], () => {
  res.proc.destroy();
  const newBlock = hydrate(require('./MyBlock'), res.model);
  res = run(newBlock);
});
```

Returns **[Block](#block)** A new block with replaced `createModel` function
                 which just returns a model that you passed as
                 second argument.

### delay

A helper function for delaying execution. Returns a Promise
which will be resolved in given amount of milliseconds. You can
use it in [task](#task) to implement some delay in execution, for
debouncing for example.

**Parameters**

-   `ms` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** An amount of milliseconds to wait

Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** A promise that resolved after given amount of milliseconds
