[
  {
    "path": ".babelrc",
    "content": "{\n  \"sourceMaps\": \"inline\",\n  \"comments\": false,\n  \"presets\": [\n    \"flow-node\"\n  ]\n}"
  },
  {
    "path": ".flowconfig",
    "content": "[ignore]\n.*/dist/.*\n.*/node_modules/babel.*\n.*/node_modules/tap/*\n.*/node_modules/json5/test/*\n.*/node_modules/kefir/*\n.*/node_modules/documentation/*\n\n[libs]\n\n[include]\n\n[options]\n\nsuppress_comment= \\\\(.\\\\|\\n\\\\)*\\\\@FlowIssue\nsuppress_comment= \\\\(.\\\\|\\n\\\\)*\\\\@FlowIgnore\nexperimental.strict_type_args=true\n"
  },
  {
    "path": ".gitignore",
    "content": "lib\ndist\n**/*.js\n**/*.flow\n!src/**/*.js\n!src/**/*.flow\n!test/**/*.js\n!test/**/*.flow"
  },
  {
    "path": ".npmignore",
    "content": "*~\n~*\n!dist\n!lib\n!**/*.js\n!**/*.flow"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nsudo: false\nnode_js:\n- stable\ndeploy:\n  provider: npm\n  email: rfobic@gmail.com\n  on:\n    tags: true\n  api_key:\n    secure: 0SAU8CJgSNo9jMZub3DRPPpqNnYPoNPUY6lnEunPHDLxwCLOwv7s6fBrSsCOvGifp7OgqMu+gBcZQcmNf5jsLqFnm3y0xEqxkabZs2x6M7FPaY3fEr7G5jDcfgO+cqJtBFsEFgRKGoZt6yhXB8Cy8/Tr/uroyAzHLifWVQURoumfy5GelosB9Tjy1pCThGwoz+20zHUk5amqdgcJiauwsSeDRS3fpOFUn7rLlpcfP44+IzF8szOdNY5wkaL2LDgCOOcK+J5k7X0iHD7E/T7mCzekbg7HCU9Cj+3nou7QsWn/NLxhfVPwa+OCHFdPL88V+kG5hzHj92NMloezafb/jBTG2UaL9QEBoqwA/mRqjcwywT6ekFlt/E2WqaYrQcKBcDRgrp5L7L99E+OczTao0PWKPnBz9xL0/q6mbf560voLArCQznduzmt0ELV4d5rYrtUGxH/Rkt9sO+Oj62mII9ODOcqcEuxH0/8MU3NWh84aajBzBDVjOobNPPv2KmUOfe1BxPUDPw6AR+aphDfEqItHQ3zVsW3Gsx+oetdfDEYIwQhCEPWDZ/hHkRps63UxqoA7r2iRqyUaPT1yvM8KVigvRq5dph8a4w47m8Fz9ckZp/j1l9e53QXAB/EYw/ziqxc9ihc1TJCBKGY61rMWeRzoKehFd4pgjsTJIQIIeU4=\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Community Participation Guidelines\n\nThis repository is governed by Mozilla's code of conduct and etiquette guidelines. \nFor more details, please read the\n[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/). \n\n## How to Report\nFor more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.\n\n<!--\n## Project Specific Etiquette\n\nIn some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).\nPlease update for your project.\n-->\n"
  },
  {
    "path": "History.md",
    "content": "# Changes\n\n## 0.0.3 / 2012-12-02\n\n  - Implement [model](./model) abstraction that can be used to map data to\n    a reactors that handle IO for the specific components in the application.\n  - Implement [collection](./collection) abstraction that is similar to model\n    but handles collections of things.\n  - Added some examples.\n  - Tests.\n\n## 0.0.2 / 2012-10-23\n\n  - Implement notion of [state](./state.js) that can be `diff`-ed & `patch`-ed.\n  - Implement [writer](./writer.js) high order function for making `write`-ers\n    that can reflect state changes on the output.\n\n## 0.0.1 / 2012-10-20\n\n  - Initial draft\n"
  },
  {
    "path": "License.md",
    "content": "Copyright 2012 Irakli Gozalishvili. All rights reserved.\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to\ndeal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or\nsell copies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\nIN THE SOFTWARE.\n"
  },
  {
    "path": "Readme.md",
    "content": "# reflex [![NPM version][version.icon]][version.url] [![Build Status][travis.icon]][travis.url] [![Gitter][gitter.icon]][gitter.url] [![styled with prettier][prettier.icon]][prettier.url]\n\n\nReflex is a functional reactive UI library that is heavily inspired by (pretty much is a port of) [elm][] and it's amazingly simple yet powerful [architecture][elm architecture] where \"[flux][]\" in [react][] terms is simply a byproduct of a pattern. In order to keep a major attraction of [elm][] &mdash; [algebraic data types][] & type safety &mdash; the library uses [flow][], a static type checker for JS. All types are separated from implementation though, so it's your call if you want to take advantage of it or just ignore it.\n\nThe library is designed such that view drivers ([react][react-driver], [virtual-dom][virtual-dom-driver] & possibly more in the future) can be swapped without any changes to the application code base. In fact there is not a built-in view driver, so it's up to the user to choose one. In fact it's pretty easy to write a driver that would directly manipulate DOM.\n\n## Install\n\n    npm install reflex\n\n## Examples\n\nFor examples check out examples directory of either [virtual-dom][virtual-dom-driver] or [react][react-driver] drivers, in fact examples are identical only diff is one line which is path of imported driver.\n\n[elm]:http://elm-lang.org\n[elm architecture]:http://elm-lang.org/guide/architecture\n[react]:http://facebook.github.io/react/\n[immutable.js]:https://facebook.github.io/immutable-js/\n[flux]:https://facebook.github.io/flux/\n[algebraic data types]:https://en.wikipedia.org/wiki/Algebraic_data_type\n[flow]:http://flowtype.org\n\n[virtual-dom-driver]:https://github.com/mozilla/reflex-virtual-dom-driver\n[react-driver]:https://github.com/mozilla/reflex-react-driver\n\n[version.url]: https://npmjs.org/package/reflex\n[version.icon]: https://img.shields.io/npm/v/reflex.svg?style=flat\n\n[travis.url]: https://travis-ci.org/mozilla/reflex\n[travis.icon]: https://img.shields.io/travis/mozilla/reflex.svg?style=flat\n\n[gitter.url]: https://gitter.im/mozilla/reflex?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge\n[gitter.icon]: https://badges.gitter.im/Join%20Chat.svg\n\n[prettier.url]:https://github.com/prettier/prettier\n[prettier.icon]:https://img.shields.io/badge/styled_with-prettier-ff69b4.svg"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"reflex\",\n  \"version\": \"1.1.0\",\n  \"description\": \"Functional reactive UI library\",\n  \"keywords\": [\"reflex\", \"reactive\", \"functional\", \"UI\"],\n  \"author\": \"Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)\",\n  \"main\": \"reflex\",\n  \"devDependencies\": {\n    \"babel-cli\": \"6.24.1\",\n    \"babel-preset-flow-node\": \"^1.0.2\",\n    \"babel-register\": \"6.24.1\",\n    \"blue-tape\": \"^1.0.0\",\n    \"documentation\": \"^4.0.0-rc.1\",\n    \"flow-bin\": \"^0.49.1\",\n    \"flow-copy-source\": \"^1.2.0\",\n    \"husky\": \"^0.14.0\",\n    \"lint-staged\": \"^4.0.0\",\n    \"prettier\": \"^1.4.4\"\n  },\n  \"scripts\": {\n    \"test\": \"npm run test:flow && npm run test:tape\",\n    \"test:tape\": \"blue-tape -r babel-register test/**/*.js\",\n    \"test:flow\": \"flow check\",\n    \"build:clear\": \"rm -rf ./*.js && rm -rf ./*.js.flow && rm -rf reflex\",\n    \"build:types\": \"flow-copy-source -v src .\",\n    \"build:node\": \"babel --out-dir . src\",\n    \"build:api\": \"documentation readme --section=API src/reflex.js\",\n    \"build:docs\": \"documentation build --document-exported src/** -f html --o docs\",\n    \"build\": \"npm run build:node && npm run build:types\",\n    \"prepublish\": \"npm run build && npm test\",\n    \"precommit\": \"lint-staged\"\n  },\n  \"lint-staged\": {\n    \"*.js\": [\"prettier --parser flow --no-semi --write\", \"git add\"]\n  },\n  \"repository\": \"https://github.com/mozilla/reflex\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"reflex-driver\": \"^1.0.2\"\n  }\n}\n"
  },
  {
    "path": "src/application.js",
    "content": "/* @flow */\n\nimport { Task } from \"./task\"\nimport { Effects } from \"./effects\"\nimport { LazyRoot } from \"./dom\"\nimport { Node } from \"reflex-driver\"\nimport type { Address } from \"./signal\"\nimport { Subscription, Feed, unsubscribe } from \"./subscription\"\nimport type { Service, Subscribe, Subscriber } from \"./subscription\"\n\nexport type Init<model, action, flags> = (\n  flags: flags\n) => [model, Effects<action>]\n\nexport type Update<model, action> = (\n  state: model,\n  action: action\n) => [model, Effects<action>]\n\nexport type View<model, action> = (\n  state: model,\n  address: Address<action>\n) => Node\n\nexport type Subscriptions<model, action> = (\n  state: model\n) => Subscription<action>\n\ntype Services<message> = {\n  nextAddress: number,\n  outbox: Address<message>,\n  active: { [key: string]: Service<message, *, *, *, *> }\n}\n\nclass Application<state, message> {\n  constructor(\n    send: Address<message>,\n    model: state,\n    view: Node,\n    task: Task<empty, void>,\n    services: Services<message>\n  ) {\n    this.send = send\n    this.model = model\n    this.view = view\n    this.task = task\n    this.services = services\n  }\n\n  send: Address<message>\n  model: state\n  view: Node\n  task: Task<empty, void>\n  services: Services<message>\n}\n\nexport type { Application }\n\nexport type Driver<model, message> = (\n  state: Application<model, message>\n) => void\n\nexport type BeginnerConfiguration<model, action> = {\n  model: model,\n  update: (model: model, action: action) => model,\n  view: View<model, action>\n}\n\nexport type AdvancedConfiguration<model, action, flags> = {\n  flags: flags,\n  init: Init<model, action, flags>,\n  update: Update<model, action>,\n  view: View<model, action>,\n  subscriptions?: Subscriptions<model, action>\n}\n\nconst first = <a, b>(xs: [a, b]): a => xs[0]\nconst second = <a, b>(xs: [a, b]): b => xs[1]\n\nexport const beginner = <model, action>(\n  configuration: BeginnerConfiguration<model, action>\n): AdvancedConfiguration<model, action, void> => ({\n  flags: void 0,\n  init: _ => [configuration.model, Effects.none],\n  update: (model, action) => [\n    configuration.update(model, action),\n    Effects.none\n  ],\n  view: configuration.view,\n  subscriptions: unsubscribe\n})\n\nexport const start = <model, message, options>(\n  configuration: AdvancedConfiguration<model, message, options>,\n  drive: Driver<model, message>\n): Application<model, message> => {\n  const { init, view, update, flags } = configuration\n  const subscriptions: Subscriptions<model, message> =\n    configuration.subscriptions == null\n      ? unsubscribe\n      : configuration.subscriptions\n\n  const send = action => {\n    const [model, fx] = update(application.model, action)\n    application.model = model\n    application.view = new LazyRoot(view, model, send)\n    application.task = fx.execute(send)\n\n    application.services = subscriptions(model).reduce(\n      subscribe,\n      application.services\n    )\n    exectueServices(application.services, send)\n    drive(application)\n  }\n\n  const [state, fx] = init(flags)\n\n  const application = new Application(\n    send,\n    state,\n    new LazyRoot(view, state, send),\n    fx.execute(send),\n    subscriptions(state).reduce(subscribe, {\n      nextAddress: 0,\n      outbox: send,\n      active: Object.create(null)\n    })\n  )\n\n  exectueServices(application.services, send)\n  drive(application)\n  return application\n}\n\nconst subscribe = <message, out, inn, model, info>(\n  services: Services<message>,\n  subscription: Subscribe<message, out, inn, model, info>\n): Services<message> => {\n  const { active, outbox } = services\n  const { feed, detail, tagger } = subscription\n  const service = active[String(feed.address)]\n\n  if (service == null || service.feed !== feed) {\n    const address = `/${++services.nextAddress}` //`\n    active[address] = spawnService(address, subscription, feed, outbox)\n  } else {\n    service.subscribers.push(subscription)\n  }\n\n  return services\n}\n\nconst spawnService = <message, out, inn, model, info>(\n  address: string,\n  subscription: Subscriber<info, out, message>,\n  feed: Feed<out, inn, model, info>,\n  outbox: Address<message>\n): Service<message, out, inn, model, info> => {\n  const subscribers = [subscription]\n  const state = feed.init()\n  feed.address = address\n  const send = (input: inn) => {\n    const [state, fx] = feed.update(service.state, input, outbox)\n    service.state = state\n    fx.execute(send)\n  }\n\n  const service = {\n    feed,\n    subscribers,\n    state,\n    inbox: send\n  }\n\n  return service\n}\n\nconst exectueServices = <a>(services: Services<a>, send: Address<a>) => {\n  for (let address in services.active) {\n    exectueService(services.active[address], send)\n  }\n}\n\nconst exectueService = <out, inn, msg, model, info>(\n  service: Service<out, inn, msg, model, info>,\n  outbox: Address<out>\n) => {\n  const { state, feed, subscribers, inbox } = service\n  const [next, fx] = feed.update(state, feed.subscribe(subscribers), outbox)\n  service.state = next\n  fx.execute(inbox)\n}\n"
  },
  {
    "path": "src/dom.js",
    "content": "/* @flow */\n\nimport { Driver, Node } from \"reflex-driver\"\nimport type { Properties } from \"reflex-driver\"\nimport type { Address } from \"./signal\"\n\nexport class LazyRoot<model, message> implements Node {\n  state: model\n  view: (state: model, mailbox: Address<message>) => *\n  mailbox: Address<message>\n  constructor(\n    view: (state: model, mailbox: Address<message>) => *,\n    state: model,\n    mailbox: Address<message>\n  ) {\n    this.state = state\n    this.view = view\n    this.mailbox = mailbox\n  }\n  renderWith<node: Node>(renderer: Driver<node>): node {\n    driver = renderer\n    return this.view(this.state, this.mailbox)\n  }\n}\n\nclass ErrorDriver implements Driver<Node> {\n  createElement(..._): Node {\n    throw new Error(`You need to use a reflex driver to create element nodes`)\n  }\n  createElementNS(..._): Node {\n    throw new Error(`You need to use a reflex driver to create element nodes`)\n  }\n  createTextNode(..._): Node {\n    throw new Error(`You need to use a reflex driver to create text nodes`)\n  }\n  createThunk(..._): Node {\n    throw new Error(`You need to use a reflex driver to create thunk nodes`)\n  }\n  render(node: Node): void {\n    throw new Error(`You need to use a reflex driver to render nodes`)\n  }\n}\n\nlet driver: Driver<any> = new ErrorDriver()\n\nexport const text = (content: string): Node => driver.createTextNode(content)\n\nexport const element = (\n  tagName: string,\n  properties: ?Properties,\n  children: ?Array<string | Node>\n): Node => driver.createElement(tagName, properties, children)\n\nexport const elementNS = (\n  namespaceURI: string,\n  tagName: string,\n  properties: ?Properties,\n  children: ?Array<string | Node>\n): Node => driver.createElementNS(namespaceURI, tagName, properties, children)\n\nexport const thunk: <a, b, c, d, e, f, g, h, i, j>(\n  key: string,\n  view: (\n    a0: a,\n    a1: b,\n    a2: c,\n    a3: d,\n    a4: e,\n    a5: f,\n    a6: g,\n    a7: h,\n    a8: i,\n    a9: j\n  ) => Node,\n  a0: a,\n  a1: b,\n  a2: c,\n  a3: d,\n  a4: e,\n  a5: f,\n  a6: g,\n  a7: h,\n  a8: i,\n  a9: j\n) => Node = (key, view, ...args) => driver.createThunk(key, view, (args: any))\n"
  },
  {
    "path": "src/effects.js",
    "content": "/* @flow */\n\nimport { Task } from \"./task\"\n\nimport type { Address } from \"./signal\"\n\nexport type Time = number\n\nconst raise = error => {\n  throw Error(\n    `Effects should be created from task that empty fail but it did fail with error ${error}`\n  )\n}\n\nconst ignore = _ => void 0\n\nconst nil = Task.succeed(void 0)\n\nconst empty = new Task((succeed, fail) => void 0)\n\nexport class Effects<a> {\n  static task<a>(task: Task<empty, a>): Effects<a> {\n    console.warn(\n      \"Effects.task is deprecated please use Effects.perform instead\"\n    )\n    return new Perform(task)\n  }\n  static perform<a>(task: Task<empty, a>): Effects<a> {\n    return new Perform(task)\n  }\n  static tick<a>(tag: (time: number) => a): Effects<a> {\n    console.warn(\n      \"Effects.tick is deprecated please use Effects.perform(Task.requestAnimationFrame().map(tag)) instead\"\n    )\n    return new Perform(Task.requestAnimationFrame().map(tag))\n  }\n  static receive<a>(action: a): Effects<a> {\n    const fx = new Perform(\n      new Task(\n        (succeed, fail) => void Promise.resolve(action).then(succeed, fail)\n      )\n    )\n    return fx\n  }\n  static batch<a>(effects: Array<Effects<a>>): Effects<a> {\n    return new Batch(effects)\n  }\n  map<b>(f: (a: a) => b): Effects<b> {\n    throw Error(\"Subclass of abstract Effect must implement map\")\n  }\n  execute(address: Address<a>): Task<empty, void> {\n    throw Error(\"Subclass of abstract Effect must implement execute\")\n  }\n  static none: Effects<any>\n  task: Task<empty, a>\n}\n\nclass Perform<a> extends Effects<a> {\n  constructor(task: Task<empty, a>) {\n    super()\n    this.task = task\n  }\n  map<b>(f: (a: a) => b): Effects<b> {\n    return new Perform(this.task.map(f))\n  }\n  execute(address: Address<a>): Task<empty, void> {\n    return this.task.chain(value => Task.send(address, value))\n  }\n}\n\nclass None<a> extends Effects<any> {\n  map<b>(f: (a: a) => b): Effects<b> {\n    return Effects.none\n  }\n  execute(address: Address<a>): Task<empty, void> {\n    return nil\n  }\n}\nEffects.none = new None()\n\nclass Batch<a> extends Effects<a> {\n  constructor(effects: Array<Effects<a>>) {\n    super()\n    this.effects = effects\n  }\n  map<b>(f: (a: a) => b): Effects<b> {\n    return new Batch(this.effects.map(effect => effect.map(f)))\n  }\n  execute(address: Address<a>): Task<empty, void> {\n    return new Task((succeed, fail) => {\n      const { effects } = this\n      const count = effects.length\n      let index = 0\n      while (index < count) {\n        const effect = effects[index]\n        if (!(effect instanceof None)) {\n          Task.fork(effect.execute(address), ignore, raise)\n        }\n\n        index = index + 1\n      }\n      succeed(void 0)\n    })\n  }\n\n  effects: Array<Effects<a>>\n}\n"
  },
  {
    "path": "src/html.js",
    "content": "/* @flow */\n\nimport { Node } from \"reflex-driver\"\nimport type { Properties } from \"reflex-driver\"\nimport { element } from \"./dom\"\n\ntype Element = (\n  properties: ?Properties,\n  children: ?Array<string | Node>\n) => Node\n\nexport type Html = {\n  a: Element,\n  abbr: Element,\n  address: Element,\n  area: Element,\n  article: Element,\n  aside: Element,\n  audio: Element,\n  b: Element,\n  base: Element,\n  bdi: Element,\n  bdo: Element,\n  big: Element,\n  blockquote: Element,\n  body: Element,\n  br: Element,\n  button: Element,\n  canvas: Element,\n  caption: Element,\n  cite: Element,\n  code: Element,\n  col: Element,\n  colgroup: Element,\n  data: Element,\n  datalist: Element,\n  dd: Element,\n  del: Element,\n  details: Element,\n  dfn: Element,\n  dialog: Element,\n  div: Element,\n  dl: Element,\n  dt: Element,\n  em: Element,\n  embed: Element,\n  fieldset: Element,\n  figcaption: Element,\n  figure: Element,\n  footer: Element,\n  form: Element,\n  h1: Element,\n  h2: Element,\n  h3: Element,\n  h4: Element,\n  h5: Element,\n  h6: Element,\n  head: Element,\n  header: Element,\n  hr: Element,\n  html: Element,\n  i: Element,\n  iframe: Element,\n  img: Element,\n  input: Element,\n  ins: Element,\n  kbd: Element,\n  keygen: Element,\n  label: Element,\n  legend: Element,\n  li: Element,\n  link: Element,\n  main: Element,\n  map: Element,\n  mark: Element,\n  menu: Element,\n  menuitem: Element,\n  meta: Element,\n  meter: Element,\n  nav: Element,\n  noscript: Element,\n  object: Element,\n  ol: Element,\n  optgroup: Element,\n  option: Element,\n  output: Element,\n  p: Element,\n  param: Element,\n  picture: Element,\n  pre: Element,\n  progress: Element,\n  q: Element,\n  rp: Element,\n  rt: Element,\n  ruby: Element,\n  s: Element,\n  samp: Element,\n  script: Element,\n  section: Element,\n  select: Element,\n  small: Element,\n  source: Element,\n  span: Element,\n  strong: Element,\n  style: Element,\n  sub: Element,\n  summary: Element,\n  sup: Element,\n  table: Element,\n  tbody: Element,\n  td: Element,\n  textarea: Element,\n  tfoot: Element,\n  th: Element,\n  thead: Element,\n  time: Element,\n  title: Element,\n  tr: Element,\n  track: Element,\n  u: Element,\n  ul: Element,\n  var: Element,\n  video: Element,\n  wbr: Element,\n  circle: Element,\n  clipPath: Element,\n  defs: Element,\n  ellipse: Element,\n  g: Element,\n  line: Element,\n  linearGradient: Element,\n  mask: Element,\n  path: Element,\n  pattern: Element,\n  polygon: Element,\n  polyline: Element,\n  radialGradient: Element,\n  rect: Element,\n  stop: Element,\n  svg: Element,\n  text: Element,\n  tspan: Element\n}\n\nexport const html: Html = [\n  \"a\",\n  \"abbr\",\n  \"address\",\n  \"area\",\n  \"article\",\n  \"aside\",\n  \"audio\",\n  \"b\",\n  \"base\",\n  \"bdi\",\n  \"bdo\",\n  \"big\",\n  \"blockquote\",\n  \"body\",\n  \"br\",\n  \"button\",\n  \"canvas\",\n  \"caption\",\n  \"cite\",\n  \"code\",\n  \"col\",\n  \"colgroup\",\n  \"data\",\n  \"datalist\",\n  \"dd\",\n  \"del\",\n  \"details\",\n  \"dfn\",\n  \"dialog\",\n  \"div\",\n  \"dl\",\n  \"dt\",\n  \"em\",\n  \"embed\",\n  \"fieldset\",\n  \"figcaption\",\n  \"figure\",\n  \"footer\",\n  \"form\",\n  \"h1\",\n  \"h2\",\n  \"h3\",\n  \"h4\",\n  \"h5\",\n  \"h6\",\n  \"head\",\n  \"header\",\n  \"hr\",\n  \"html\",\n  \"i\",\n  \"iframe\",\n  \"img\",\n  \"input\",\n  \"ins\",\n  \"kbd\",\n  \"keygen\",\n  \"label\",\n  \"legend\",\n  \"li\",\n  \"link\",\n  \"main\",\n  \"map\",\n  \"mark\",\n  \"menu\",\n  \"menuitem\",\n  \"meta\",\n  \"meter\",\n  \"nav\",\n  \"noscript\",\n  \"object\",\n  \"ol\",\n  \"optgroup\",\n  \"option\",\n  \"output\",\n  \"p\",\n  \"param\",\n  \"picture\",\n  \"pre\",\n  \"progress\",\n  \"q\",\n  \"rp\",\n  \"rt\",\n  \"ruby\",\n  \"s\",\n  \"samp\",\n  \"script\",\n  \"section\",\n  \"select\",\n  \"small\",\n  \"source\",\n  \"span\",\n  \"strong\",\n  \"style\",\n  \"sub\",\n  \"summary\",\n  \"sup\",\n  \"table\",\n  \"tbody\",\n  \"td\",\n  \"textarea\",\n  \"tfoot\",\n  \"th\",\n  \"thead\",\n  \"time\",\n  \"title\",\n  \"tr\",\n  \"track\",\n  \"u\",\n  \"ul\",\n  \"var\",\n  \"video\",\n  \"wbr\",\n  \"circle\",\n  \"clipPath\",\n  \"defs\",\n  \"ellipse\",\n  \"g\",\n  \"line\",\n  \"linearGradient\",\n  \"mask\",\n  \"path\",\n  \"pattern\",\n  \"polygon\",\n  \"polyline\",\n  \"radialGradient\",\n  \"rect\",\n  \"stop\",\n  \"svg\",\n  \"text\",\n  \"tspan\"\n].reduce((html, tagName) => {\n  const create: Element = (properties, children) =>\n    element(tagName, properties, children)\n\n  html[tagName] = create\n  return html\n}, ((Object.create(null): any): Html))\n"
  },
  {
    "path": "src/preemptive-animation-frame.js",
    "content": "/* @flow */\n\ntype Time = number\ntype State = 0 | 1 | 2\n\n// Invariants:\n// 1. In the NO_REQUEST state, there is never a scheduled animation frame.\n// 2. In the PENDING_REQUEST and EXTRA_REQUEST states, there is always exactly\n// one scheduled animation frame.\nconst NO_REQUEST = 0\nconst PENDING_REQUEST = 1\nconst EXTRA_REQUEST = 2\n\nlet nextID: number = 0\nlet state: State = NO_REQUEST\nlet requests: Array<(time: Time) => any> = []\nlet ids: Array<number> = []\n\nconst absent = new String(\"absent\")\n\nexport const requestAnimationFrame = <a>(request: (time: Time) => a) => {\n  if (state === NO_REQUEST) {\n    window.requestAnimationFrame(performAnimationFrame)\n  }\n\n  const id = ++nextID\n  requests.push(request)\n  ids.push(id)\n  state = PENDING_REQUEST\n  return id\n}\n\nexport const cancelAnimationFrame = (id: number): void => {\n  const index = ids.indexOf(id)\n  if (index >= 0) {\n    ids.splice(index, 1)\n    requests.splice(index, 1)\n  }\n}\n\nexport const forceAnimationFrame = (time: Time = window.performance.now()) =>\n  performAnimationFrame(time)\n\nconst performAnimationFrame = (time: Time) => {\n  switch (state) {\n    case NO_REQUEST:\n      // This state should not be possible. How can there be no\n      // request, yet somehow we are actively fulfilling a\n      // request?\n      throw Error(`Unexpected frame request`)\n    case PENDING_REQUEST:\n      // At this point, we do not *know* that another frame is\n      // needed, but we make an extra frame request just in\n      // case. It's possible to drop a frame if frame is requested\n      // too late, so we just do it preemptively.\n      window.requestAnimationFrame(performAnimationFrame)\n      state = EXTRA_REQUEST\n      ids.splice(0)\n      dispatchAnimationFrame(requests.splice(0), 0, time)\n      break\n    case EXTRA_REQUEST:\n      // Turns out the extra request was not needed, so we will\n      // stop requesting. No reason to call it all the time if\n      // no one needs it.\n      state = NO_REQUEST\n      break\n  }\n}\n\nconst dispatchAnimationFrame = <a>(\n  requests: Array<(time: Time) => a>,\n  index: number,\n  time: Time\n) => {\n  let exception: String | Error = absent\n  const count = requests.length\n  try {\n    while (index < count) {\n      const request = requests[index]\n      index = index + 1\n      request(time)\n    }\n  } catch (error) {\n    exception = error\n  }\n\n  if (index < count) {\n    dispatchAnimationFrame(requests, index, time)\n  }\n\n  if (exception != absent) {\n    throw exception\n  }\n}\n"
  },
  {
    "path": "src/reflex.js",
    "content": "/* @flow */\n\nimport type { Node, Properties, Style, Attributes } from \"reflex-driver\"\n\nexport type DOM = Node\nexport { Node, Driver } from \"reflex-driver\"\n\nexport type { Address } from \"./signal\"\n\nexport type { Properties, Attributes, Style } from \"reflex-driver\"\n\nexport { Subscription, subscribe, unsubscribe } from \"./subscription\"\n\nexport type {\n  Application,\n  AdvancedConfiguration,\n  BeginnerConfiguration\n} from \"./application\"\n\nexport type { Init, Update, View } from \"./application\"\n\nexport { forward } from \"./signal\"\nexport { element, elementNS, text, thunk } from \"./dom\"\nexport { html } from \"./html\"\nexport { start, beginner } from \"./application\"\nexport { Task } from \"./task\"\nexport { Effects } from \"./effects\"\n"
  },
  {
    "path": "src/signal.js",
    "content": "/* @flow */\n\nexport type Address<a> = (input: a) => void\n\nconst Forward = <a, b>(address: Address<b>, tag: (a: a) => b): Address<a> => {\n  const forward = (message: a) => address(tag(message))\n  forward.to = address\n  forward.tag = tag\n  return forward\n}\n\nif (global[\"reflex/address\"] == null) {\n  global[\"reflex/address\"] = 0\n}\n\n// Create a new address. This address will tag each message it receives and then\n// forward it along to the given address.\n// Example:\n//\n// const Remove = target => {type: \"Remove\", target}\n// removeAddress = forward(address, Remove)\n//\n// Above example created `removeAddress` tags each message with `Remove` tag\n// before forwarding them to a general `address`.\nexport const forward = <a, b>(\n  address: Address<a>,\n  tag: (value: b) => a\n): Address<b> => {\n  // Genrate ID for each address that has a forwarding addresses so that\n  // forwarding addresses could be cached by that id and a tag-ing function.\n  const id =\n    address.id != null ? address.id : (address.id = global[\"reflex/address\"]++)\n  const key = `reflex/address/${id}`\n\n  return tag[key] || (tag[key] = Forward(address, tag))\n}\n"
  },
  {
    "path": "src/subscription.js",
    "content": "/* @flow */\n\nimport { Effects } from \"./effects\"\nimport type { Address } from \"./signal\"\n\ntype Tagger<a, b> = (value: a) => b\n\nexport interface Subscriber<info, inn, out> {\n  detail: info,\n  tagger: Tagger<inn, out>\n}\n\nexport type Service<message, out, inn, model, info> = {\n  inbox: Address<inn>,\n  subscribers: Array<Subscriber<info, out, message>>,\n  state: model,\n  feed: Feed<out, inn, model, info>\n}\n\nexport interface Feed<out, inn, model, info> {\n  address?: string,\n  init(): model,\n  subscribe<message>(subscribers: Array<Subscriber<info, out, message>>): inn,\n  update<message>(\n    state: model,\n    input: inn,\n    outbox: Address<message>\n  ): [model, Effects<inn>]\n}\n\nexport class Subscription<a> {\n  static none: Subscription<*>\n  static batch(subscriptions: Array<Subscription<a>>): Subscription<a> {\n    return new Batch(subscriptions)\n  }\n  map<b>(tag: (value: a) => b): Subscription<b> {\n    return this.map(tag)\n  }\n  reduce<state>(\n    reducer: (result: state, input: Subscribe<a, *, *, *, *>) => state,\n    init: state\n  ): state {\n    return init\n  }\n}\n\nexport class Subscribe<out, inn, msg, model, info> extends Subscription<out>\n  implements Subscriber<info, inn, out> {\n  feed: Feed<inn, msg, model, info>\n  detail: info\n  tagger: Tagger<inn, out>\n\n  constructor(\n    feed: Feed<inn, msg, model, info>,\n    detail: info,\n    tagger: Tagger<inn, out>\n  ) {\n    super()\n    this.feed = feed\n    this.detail = detail\n    this.tagger = tagger\n  }\n  map<b>(tag: (value: out) => b): Subscription<b> {\n    const decoder = (value: inn): b => tag(this.tagger(value))\n    return new Subscribe(this.feed, this.detail, decoder)\n  }\n  reduce<state>(\n    reducer: (\n      result: state,\n      input: Subscribe<out, inn, msg, model, info>\n    ) => state,\n    init: state\n  ): state {\n    return reducer(init, this)\n  }\n}\n\nclass Batch<a> extends Subscription<a> {\n  constructor(subscriptions: Array<Subscription<a>>) {\n    super()\n    this.subscriptions = subscriptions\n  }\n  map<b>(tag: (value: a) => b): Subscription<b> {\n    const subscriptions = this.subscriptions.map($ => $.map(tag))\n    return new Batch(subscriptions)\n  }\n  reduce<state>(\n    reducer: (result: state, input: Subscribe<a, *, *, *, *>) => state,\n    init: state\n  ): state {\n    return this.subscriptions.reduce(\n      (result: state, subscription: Subscription<a>): state =>\n        subscription.reduce(reducer, result),\n      init\n    )\n  }\n  subscriptions: Array<Subscription<a>>\n}\n\nexport const subscribe = <outer, inner, message, model, info>(\n  feed: Feed<inner, message, model, info>,\n  detail: info,\n  tagger: Tagger<inner, outer>\n): Subscription<outer> => new Subscribe(feed, detail, tagger)\n\nconst none: Subscription<any> = new Batch([])\nexport const unsubscribe = <a>(_: mixed): Subscription<a> => none\nSubscription.none = none\n"
  },
  {
    "path": "src/task.js",
    "content": "/* @flow */\n\nimport type { Address } from \"./signal\"\nimport {\n  requestAnimationFrame,\n  cancelAnimationFrame\n} from \"./preemptive-animation-frame\"\n\nexport type ThreadID = number\nexport type Time = number\nexport type ProcessID = number\n\nconst raise = error => {\n  throw Error(\n    `Task was not supposet to never fail but it did fail with error ${error}`\n  )\n}\n\nconst ignore = _ => void 0\n\nexport interface Process<error, value, message, reason> {\n  id: ProcessID,\n  isActive: boolean,\n  kill(reson: reason): void\n}\n\nexport class Task<x, a> {\n  static create<x, a>(\n    execute: (succeed: (a: a) => void, fail: (x: x) => void) => void\n  ): Task<x, a> {\n    console.warn(\"Task.create is deprecated API use new Task instead\")\n    return new Task(execute)\n  }\n  static future<x, a>(request: () => Promise<a>): Task<x, a> {\n    console.warn(\"Task.future is deprecated API use new Task instead\")\n    return new Future(request)\n  }\n  static succeed<x, a>(value: a): Task<x, a> {\n    return new Succeed(value)\n  }\n\n  static fail<x, a>(error: x): Task<x, a> {\n    return new Fail(error)\n  }\n\n  static spawn<x, y, a>(task: Task<x, a>): Task<y, ThreadID> {\n    return new Spawn(task)\n  }\n\n  static sleep<x>(time: Time): Task<x, void> {\n    return new Sleep(time)\n  }\n\n  static requestAnimationFrame<x>(): Task<x, Time> {\n    return new AnimationFrame()\n  }\n\n  static send<x, a>(address: Address<a>, message: a): Task<x, void> {\n    return new Send(address, message)\n  }\n\n  static fork<x, a, message, reason>(\n    task: Task<x, a>,\n    onSucceed: (a: a) => void,\n    onFail: (x: x) => void\n  ): Process<x, a, message, reason> {\n    return Thread.fork(task, onSucceed, onFail)\n  }\n\n  static perform(task: Task<empty, void>): void {\n    Thread.fork(task, ignore, raise)\n  }\n\n  constructor<handle>(\n    execute: ?(succeed: (a: a) => void, fail: (x: x) => void) => handle,\n    cancel: ?(handle: handle) => void\n  ) {\n    this.type = \"Task\"\n    const task = (this: any)\n    if (execute != null) {\n      task.fork = execute\n    }\n    if (cancel != null) {\n      task.abort = cancel\n    }\n  }\n  chain<b>(next: (a: a) => Task<x, b>): Task<x, b> {\n    return new Chain(this, next)\n  }\n  map<b>(f: (input: a) => b): Task<x, b> {\n    return new Map(this, f)\n  }\n  capture<y>(handle: (error: x) => Task<y, a>): Task<y, a> {\n    return new Capture(this, handle)\n  }\n  format<y>(f: (input: x) => y): Task<y, a> {\n    return new Format(this, f)\n  }\n  recover<y>(regain: (error: x) => a): Task<y, a> {\n    return new Recover(this, regain)\n  }\n  fork(succeed: (a: a) => void, fail: (x: x) => void): * {\n    return this.execute(succeed, fail)\n  }\n  abort(token: *): void {\n    return this.cancel(token)\n  }\n\n  type: *\n  execute: (succeed: (a: a) => void, fail: (x: x) => void) => *\n  cancel: (handle: *) => void\n}\n\nclass Succeed<x, a> extends Task<x, a> {\n  constructor(value: a) {\n    super()\n    this.type = \"Succeed\"\n    this.value = value\n  }\n  fork(succeed: (a: a) => void, fail: (x: x) => void): void {\n    succeed(this.value)\n  }\n\n  type: \"Succeed\"\n  value: a\n}\n\nclass Fail<x, a> extends Task<x, a> {\n  constructor(error: x) {\n    super()\n    this.type = \"Fail\"\n    this.error = error\n  }\n  fork(succeed: (a: a) => void, fail: (x: x) => void): void {\n    fail(this.error)\n  }\n\n  type: \"Fail\"\n  error: x\n}\n\nclass Sleep<x, a: void> extends Task<x, void> {\n  constructor(time: Time) {\n    super()\n    this.time = time\n  }\n  fork(succeed: (a: a) => void, fail: (x: x) => void): number {\n    return setTimeout(succeed, this.time, void 0)\n  }\n  abort(id: number): void {\n    clearTimeout(id)\n  }\n\n  time: Time\n}\n\nclass AnimationFrame<x> extends Task<x, Time> {\n  constructor() {\n    super()\n  }\n  fork(succeed: (a: Time) => void, fail: (x: x) => void): number {\n    return requestAnimationFrame(succeed)\n  }\n  abort(id: number): void {\n    cancelAnimationFrame(id)\n  }\n}\n\nlet threadID = 0\nclass Spawn<x, y, a> extends Task<y, ThreadID> {\n  constructor(task: Task<x, a>) {\n    super()\n    this.task = task\n  }\n  fork(succeed: (a: ThreadID) => void, fail: (x: y) => void): void {\n    Promise.resolve(null).then(_ => Task.fork(this.task, noop, noop))\n\n    succeed(++threadID)\n  }\n\n  task: Task<x, a>\n}\n\nclass Send<x, a> extends Task<x, void> {\n  constructor(address: Address<a>, message: a) {\n    super()\n    this.message = message\n    this.address = address\n  }\n  fork(succeed: (a: void) => void, fail: (x: x) => void): void {\n    succeed(void this.address(this.message))\n  }\n\n  message: a\n  address: Address<a>\n}\n\nclass Future<x, a> extends Task<x, a> {\n  constructor(request: () => Promise<a>) {\n    super()\n    this.request = request\n  }\n  fork(succeed: (a: a) => void, fail: (x: x) => void): void {\n    this.request().then(succeed, fail)\n  }\n\n  request: () => Promise<a>\n}\n\nclass Then<x, a, b> extends Task<x, b> {\n  constructor(task: Task<x, a>) {\n    super()\n    this.type = \"Then\"\n    this.task = task\n  }\n  fork(succeed: (value: b) => void, fail: (error: x) => void): void {\n    this.task.fork(\n      (value: a): void => void this.next(value).fork(succeed, fail),\n      fail\n    )\n  }\n  next(input: a): Task<x, b> {\n    throw Error(\"Subclass of absract Then must implement next method\")\n  }\n\n  type: \"Then\"\n  task: Task<x, a>\n}\n\nclass Chain<x, a, b> extends Then<x, a, b> {\n  constructor(task: Task<x, a>, next: (input: a) => Task<x, b>) {\n    super(task)\n    this.chainer = next\n  }\n  next(input: a): Task<x, b> {\n    return this.chainer(input)\n  }\n\n  chainer: (input: a) => Task<x, b>\n}\n\nclass Map<x, a, b> extends Then<x, a, b> {\n  constructor(task: Task<x, a>, mapper: (input: a) => b) {\n    // Note: Had to trick flow into thinking that `Format.prototype.handle` was\n    // passed, otherwise it fails to infer polymorphic nature.\n    super(task)\n    this.mapper = mapper\n  }\n  next(input: a): Task<x, b> {\n    return new Succeed(this.mapper(input))\n  }\n\n  mapper: (input: a) => b\n}\n\nclass Catch<x, y, a> extends Task<y, a> {\n  constructor(task: Task<x, a>) {\n    super()\n    this.type = \"Catch\"\n    this.task = task\n  }\n  fork(succeed: (value: a) => void, fail: (error: y) => void): void {\n    this.task.fork(\n      succeed,\n      error => void this.handle(error).fork(succeed, fail)\n    )\n  }\n  handle(error: x): Task<y, a> {\n    throw Error(\"Subclass of absract Catch must implement handle method\")\n  }\n\n  type: \"Catch\"\n  task: Task<x, a>\n}\n\nclass Capture<x, y, a> extends Catch<x, y, a> {\n  constructor(task: Task<x, a>, handle: (error: x) => Task<y, a>) {\n    super(task)\n    this.capturer = handle\n  }\n\n  handle(error: x): Task<y, a> {\n    return this.capturer(error)\n  }\n\n  capturer: (error: x) => Task<y, a>\n}\n\nclass Recover<x, y, a> extends Catch<x, y, a> {\n  constructor(task: Task<x, a>, regain: (error: x) => a) {\n    super(task)\n    this.regain = regain\n  }\n  handle(error: x): Task<y, a> {\n    return new Succeed(this.regain(error))\n  }\n\n  regain: (error: x) => a\n}\n\nclass Format<x, y, a> extends Catch<x, y, a> {\n  constructor(task: Task<x, a>, formatter: (error: x) => y) {\n    super(task)\n    this.formatter = formatter\n  }\n  handle(error: x): Task<y, a> {\n    return new Fail(this.formatter(error))\n  }\n\n  formatter: (error: x) => y\n}\n\nconst noop = () => void 0\n\nlet nextID = 0\n\ntype Root<x, a> =\n  | Succeed<x, a>\n  | Fail<x, a>\n  | Then<x, *, a>\n  | Catch<*, x, a>\n  | Task<x, a>\n\nclass Thread<error, value, message, reason> {\n  id: ProcessID\n  root: Root<*, *>\n  stack: Array<Catch<*, *, *> | Then<*, *, *>>\n  position: number\n  mailbox: Array<message>\n  abortHandle: *\n  isActive: boolean\n  succeed: (input: value) => void\n  fail: (error: error) => void\n  isPending: boolean\n  isPaused: boolean\n  success: ?Succeed<*, *>\n  failure: ?Fail<*, *>\n  onSucceed: <value>(input: value) => void\n  onFail: <error>(error: error) => void\n  static fork<error, value, message, reason>(\n    task: Task<error, value>,\n    onSucceed: (input: value) => void,\n    onFail: (error: error) => void\n  ): Process<error, value, message, reason> {\n    const process = new Thread()\n    process.id = ++nextID\n    process.position = 0\n    process.root = task\n    process.stack = []\n    process.mailbox = []\n    process.abortHandle = null\n    process.isActive = true\n    process.isPending = false\n    process.isPaused = true\n    process.success = null\n    process.failure = null\n    process.succeed = onSucceed\n    process.fail = onFail\n    process.onSucceed = process.onSucceed.bind(process)\n    process.onFail = process.onFail.bind(process)\n    process.schedule()\n    return process\n  }\n  onSucceed(ok) {\n    if (this.isPending) {\n      this.isPending = false\n      this.abortHandle = null\n\n      if (this.success != null) {\n        this.success.value = ok\n      } else {\n        this.success = new Succeed(ok)\n      }\n\n      this.root = this.success\n      this.schedule()\n    }\n  }\n  onFail(failure) {\n    if (this.isPending) {\n      this.isPending = false\n      this.abortHandle = null\n\n      if (this.failure != null) {\n        this.failure.error = failure\n      } else {\n        this.failure = new Fail(failure)\n      }\n\n      this.root = this.failure\n      this.schedule()\n    }\n  }\n  kill(exit: reason) {\n    if (this.isActive) {\n      this.isActive = false\n      if (this.root.abort) {\n        this.root.abort(this.abortHandle)\n      }\n    }\n  }\n  schedule() {\n    if (this.isPaused) {\n      this.isPaused = false\n      this.step()\n    }\n  }\n  step() {\n    const process = this\n    while (process.isActive) {\n      const root = process.root\n      switch (root.type) {\n        case \"Succeed\": {\n          const task: Succeed<*, *> = (root: any)\n          // If task succeeded skip all the error handling.\n          while (\n            process.position < process.stack.length &&\n            process.stack[process.position] instanceof Catch\n          ) {\n            process.position++\n          }\n\n          // If end of the stack is reached then break\n          if (process.position >= process.stack.length) {\n            if (process.succeed != null) {\n              process.succeed(task.value)\n            }\n            return\n          }\n\n          // Otherwise step into next task.\n          const then = process.stack[process.position++]\n          if (then instanceof Then) {\n            process.root = then.next(task.value)\n          }\n\n          break\n        }\n        case \"Fail\": {\n          const task: Fail<*, *> = (root: any)\n          // If task fails skip all the chaining.\n          while (\n            process.position < process.stack.length &&\n            process.stack[process.position] instanceof Then\n          ) {\n            process.position++\n          }\n\n          // If end of the stack is reached then break.\n          if (this.position >= process.stack.length) {\n            if (process.fail != null) {\n              process.fail(task.error)\n            }\n\n            return\n          }\n\n          // Otherwise step into next task.\n          const _catch = process.stack[process.position++]\n          if (_catch instanceof Catch) {\n            process.root = _catch.handle(task.error)\n          }\n\n          break\n        }\n        case \"Then\": {\n          const task: Then<*, *, *> = (root: any)\n          if (process.position === 0) {\n            process.stack.unshift(task)\n          } else {\n            process.stack[--process.position] = task\n          }\n\n          process.root = task.task\n\n          break\n        }\n        case \"Catch\": {\n          const task: Catch<*, *, *> = (root: any)\n          if (process.position === 0) {\n            process.stack.unshift(task)\n          } else {\n            process.stack[--process.position] = task\n          }\n\n          process.root = task.task\n\n          break\n        }\n        default: {\n          const task = root\n          process.isPending = true\n          process.abortHandle = task.fork(process.onSucceed, process.onFail)\n          process.isPaused = process.isPending\n          if (this.isPending) {\n            return\n          }\n\n          break\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "test/test-api.js",
    "content": "import test from \"blue-tape\"\nimport * as Reflex from \"../\"\n\ntest(\"test exported api\", async assert => {\n  assert.ok(typeof Reflex.node, \"function\")\n\n  assert.ok(typeof Reflex.html, \"object\")\n  assert.ok(typeof Reflex.html.div, \"function\")\n\n  assert.ok(typeof Reflex.thunk, \"function\")\n  assert.ok(typeof Reflex.send, \"function\")\n  assert.ok(typeof Reflex.forward, \"function\")\n\n  assert.ok(typeof Reflex.Application, \"function\")\n\n  assert.ok(typeof Reflex.Task.succeed, \"function\")\n  assert.ok(typeof Reflex.Task.fail, \"function\")\n  assert.ok(typeof Reflex.Task.io, \"function\")\n  assert.ok(typeof Reflex.Task.onSuccess, \"function\")\n  assert.ok(typeof Reflex.Task.onFailure, \"function\")\n  assert.ok(typeof Reflex.Task.perform, \"function\")\n  assert.ok(typeof Reflex.Task.run, \"function\")\n})\n"
  }
]