perform = (type, task, ...[init]) =>
  // eslint-disable-next-line require-yield
  spawn(type, async function * (context) {
    return await task(context)
  }, init)
Takes the action `type`, a `task` (in form of async function) and an optional
`init` parameters to produce a `doX` style action creator. On exectuion
`{ type, task }` actions will be dispatched, where `task` represents a state
(machine) of the executed task, which proceeds as follows:

- At the start of the execution, task will have an `Init` status, which is
 dispatched just once: `{ status: 'Init' id: Symbol, init: Init}`. An `id`
 is unique identifier of the task (kind of like PID) and `init` is an
 optional parameter that was passed to `perform` (Which can be useful in
 certain reducers and middleware that need to keep track of state).

- Once task is finishes, action with status `Exit` is dispatced just once:
  `{ status: 'Exit', id: Symbol, duration: number, result: Result<Error, Success> }`
  with some new new fields:
    - `duration` - Is a time it took a task from `Init` to `Exit` in ms.
    - `result` - Is a result of the task. On succesful completion it is
      `{ok:true, value:Success}` (value is return value of the async
      function). On failure it is `{ok:false, error:Error}` (`error` is an
      expception thrown, or a rejection reason of the promise).

@template {string} Type - Corresponds to `action.type` for all the actions
@template Success - Type of the `action.task.result.vaule` when task is
complete successfully. It is also a value of the promise returned by
running `store.doX` created by this decorator.
@template Init - Type of the initialization paramater.
@template State - Type of the `context.getState()` for this task.
@template {Object} StoreExt - Store extension.
@template {Object} ContextExt - Context extension
@template {BundlerContext<State, Perform<Type, Error, Success, Init>, StoreExt, ContextExt>} Context

@param {Type} type - Type of the actions this will dispatch.
@param {(context:Context) => Promise<Success>} task
@param {Init[]} rest
@returns {(context:Context) => Promise<Success>}