{"_id":"fsm-iterator","_rev":"6-596831cac84903d47aaae272bca76a30","name":"fsm-iterator","description":"A finite state machine iterator for JavaScript","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"fsm-iterator","version":"1.0.0","description":"A finite state machine iterator for JavaScript","main":"lib/index.js","files":["lib","src"],"scripts":{"build":"babel src --out-dir lib","clean":"rimraf lib","lint":"eslint src __tests__","prepublish":"npm run clean && npm run build","test":"jest"},"repository":{"type":"git","url":"git+https://github.com/jfairbank/fsm-iterator.git"},"keywords":["iterator","iterable","generator","finite state machine","state machine","state","fsm"],"author":{"name":"Jeremy Fairbank","email":"elpapapollo@gmail.com","url":"http://jeremyfairbank.com"},"license":"MIT","bugs":{"url":"https://github.com/jfairbank/fsm-iterator/issues"},"homepage":"https://github.com/jfairbank/fsm-iterator#readme","devDependencies":{"babel-cli":"^6.16.0","babel-core":"^6.17.0","babel-plugin-transform-object-rest-spread":"^6.16.0","babel-preset-es2015":"^6.16.0","eslint":"^3.7.1","eslint-config-airbnb-base":"^8.0.0","eslint-import-resolver-node":"^0.2.3","eslint-plugin-import":"^1.16.0","jest":"^16.0.1","rimraf":"^2.5.4"},"gitHead":"f6b2f6917482960ef9a7043dfac76950417812ea","_id":"fsm-iterator@1.0.0","_shasum":"b82821315d6d5d0f44c9f3228f41851b59dc45c6","_from":".","_npmVersion":"3.10.3","_nodeVersion":"6.5.0","_npmUser":{"name":"elpapapollo","email":"elpapapollo@gmail.com"},"maintainers":[{"name":"elpapapollo","email":"elpapapollo@gmail.com"}],"dist":{"shasum":"b82821315d6d5d0f44c9f3228f41851b59dc45c6","tarball":"https://registry.npmjs.org/fsm-iterator/-/fsm-iterator-1.0.0.tgz","integrity":"sha512-yA/tiqqpbGrvSf0Ru4Id2Xj0RCvKLZgTrnoEKQm3LNMQxQq1czrzrsRzitX10IUFdvflwn7EGaCXJgSkWovplA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID4iAN6acLDAxA5pqe9T73bUA9ogN4CPJqJ35+gJPtkXAiEAiq4LrD3mM2Dl5QPEu+YVxYICjAng/0RUXr5uOXK9G0g="}]},"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/fsm-iterator-1.0.0.tgz_1475769608549_0.9873510545585304"}},"1.1.0":{"name":"fsm-iterator","version":"1.1.0","description":"A finite state machine iterator for JavaScript","main":"lib/index.js","files":["lib","src"],"scripts":{"build":"babel src --out-dir lib","clean":"rimraf lib","lint":"eslint src __tests__","prepublish":"npm run clean && npm run build","test":"jest"},"repository":{"type":"git","url":"git+https://github.com/jfairbank/fsm-iterator.git"},"keywords":["iterator","iterable","generator","finite state machine","state machine","state","fsm"],"author":{"name":"Jeremy Fairbank","email":"elpapapollo@gmail.com","url":"http://jeremyfairbank.com"},"license":"MIT","bugs":{"url":"https://github.com/jfairbank/fsm-iterator/issues"},"homepage":"https://github.com/jfairbank/fsm-iterator#readme","devDependencies":{"babel-cli":"^6.16.0","babel-core":"^6.17.0","babel-eslint":"^7.2.2","babel-jest":"^16.0.0","babel-plugin-transform-object-rest-spread":"^6.16.0","babel-polyfill":"^6.16.0","babel-preset-es2015":"^6.16.0","eslint":"^3.7.1","eslint-config-airbnb-base":"^8.0.0","eslint-import-resolver-node":"^0.2.3","eslint-plugin-import":"^1.16.0","jest":"^16.0.1","rimraf":"^2.5.4"},"gitHead":"5db553f453c2f5713d6d6976f01bbddbf1b3f3fd","_id":"fsm-iterator@1.1.0","_shasum":"337de45de19eb205788cf02e3a955ec206760dec","_from":".","_npmVersion":"3.10.10","_nodeVersion":"6.10.0","_npmUser":{"name":"elpapapollo","email":"elpapapollo@gmail.com"},"maintainers":[{"name":"elpapapollo","email":"elpapapollo@gmail.com"}],"dist":{"shasum":"337de45de19eb205788cf02e3a955ec206760dec","tarball":"https://registry.npmjs.org/fsm-iterator/-/fsm-iterator-1.1.0.tgz","integrity":"sha512-hg47CNYdIGJ5m9WSKh617LHRdvJo4PiF0VkncFLwPVxKvBEQfSPd1qx/xLV/eSusewEu0C8eUFrsLsWlBgIcOg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIESoaKPI2Lcy8H87hvPKuJMGDdkU9N3/zKJZc5MXUxmJAiBr2pWXfeYZug0YtTgri5s5OBpAoYl9An+iV0qsbhE7OA=="}]},"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/fsm-iterator-1.1.0.tgz_1492203253536_0.39349771081469953"}}},"readme":"# fsm-iterator\n\n[![Travis branch](https://img.shields.io/travis/jfairbank/fsm-iterator/master.svg?style=flat-square)](https://travis-ci.org/jfairbank/fsm-iterator)\n[![npm](https://img.shields.io/npm/v/fsm-iterator.svg?style=flat-square)](https://www.npmjs.com/package/fsm-iterator)\n\nA finite state machine iterator for JavaScript.\n\nUse fsm-iterator to implement a finite state machine generator function without\nthe need for generator `function*` syntax. This is a perfect for library authors\nthat need to use generators but don't want to burden their ES5 users with a\ntranspiled generator runtime.\n\n## Install\n\n```\nnpm install --save fsm-iterator\n```\n\n## Usage\n\nThe default export is the `fsmIterator` function. It takes an initial state as\nthe first argument and the state machine as an object literal as the second\nargument. Each key-value pair of your definition is a state and a function to\nhandle that state. States can be strings or symbols.\n\nThe state function takes any value that was passed into the `next` method of the\niterator as the first argument and the finite state machine definition itself as\nthe second argument.  This allows you to act on values passed back into the\n\"generator\" and delegate to other states. The finite state machine argument also\nincludes a `previousState` property if you need to use it.\n\nTo yield a value from your state function return an object literal with the\n`value` property set to the yielded value. To specify the next state to\ntransition to, set the `next` property to the next state. You can end the\niterator by including the `done` property set to `true`. If you don't supply the\n`next` property, then the iterator will stay in the same state. This is fine if\nyou want to loop on one thing, but if you have multiple states, then remember to\nuse the `next` property.\n\nYou may include a `throw` function to handle the `throw` method of the iterator.\nIt takes the thrown error as the first argument and the finite state machine\ndefinition as the second argument. If you don't supply a `throw` function, then\nyour iterator will stop, rethrowing the error.\n\nYou may intercept the iterator's `return` method by supplying a `return`\nfunction that receives the passed-in return value as the first argument and the\nfinite state machine definition as the second argument. You can return your own\nreturn value or keep your iterator returning. This is similar to handling the\n`finally` block in a `try..finally` statement in a ES2015 generator function.\n\n```js\n// ES2015 modules\nimport fsmIterator from 'fsm-iterator';\n\n// ES5 and CJS\nvar fsmIterator = require('fsm-iterator').default;\n\nconst FOO = 'FOO';\nconst BAR = 'BAR';\nconst BAZ = 'BAZ';\n\nconst definition = {\n  [FOO]: () => ({\n    value: 'foo',\n    next: BAR,\n  }),\n\n  [BAR](x) {\n    if (x < 0) {\n      return {\n        value: x / 2,\n        done: true,\n      };\n    }\n\n    return {\n      value: x * 2,\n      next: BAZ,\n    };\n  },\n\n  [BAZ]: (_, fsm) => ({\n    value: `baz : ${fsm.previousState}`,\n    next: FOO,\n  }),\n\n  return(value, fsm) {\n    return {\n      value: 'my own return',\n      done: true,\n    }\n  },\n\n  throw: (e, fsm) => ({\n    value: `${e.message} : ${fsm.previousState}`,\n    next: FOO,\n  }),\n};\n\n// Normal path\nlet iterator = fsmIterator(FOO, definition);\n\niterator.next();    // { value: 'foo', done: false }\niterator.next(21);  // { value: 42, done: false }\niterator.next();    // { value: 'baz : BAR', done: false }\niterator.next();    // { value: 'foo', done: false }\niterator.next(-42); // { value: -21, done: true }\n\n// Throwing\nconst error = new Error('error');\niterator = fsmIterator(FOO, definition);\n\niterator.next();       // { value: 'foo', done: false }\niterator.next(21);     // { value: 42, done: false }\niterator.throw(error); // { value: 'error : BAR', done: false }\niterator.next();       // { value: 'foo', done: false }\n\n// Returning\niterator = fsmIterator(FOO, definition);\n\niterator.next();            // { value: 'foo', done: false }\niterator.next(21);          // { value: 42, done: false }\niterator.return('the end'); // { value: 'my own return', done: true }\n```\n\n#### Equivalent ES2015 Generator\n\nHere is the comparable ES2015 generator for the previous example.\n\n```js\nconst FOO = 'FOO';\nconst BAR = 'BAR';\nconst BAZ = 'BAZ';\n\nfunction* myGenerator() {\n  let currentState = FOO;\n  let previousState = null;\n\n  function setState(newState) {\n    previousState = currentState;\n    currentState = newState;\n  }\n\n  while (true) {\n    try {\n      const x = yield 'foo';\n\n      setState(BAR);\n\n      if (x < 0) {\n        return x / 2;\n      }\n\n      yield x * 2;\n\n      setState(BAZ);\n\n      yield `baz : ${previousState}`;\n\n      setState(FOO);\n    } catch (e) {\n      setState(FOO);\n\n      yield `${e.message} : ${previousState}`;\n    } finally {\n      return 'my own return';\n    }\n  }\n}\n```\n\n#### Another Example\n\nHere is the implementation of the `router` saga from\n[redux-saga-router](https://github.com/jfairbank/redux-saga-router) using\n`fsmIterator`.\n\n```js\nimport { call, take } from 'redux-saga/effects';\nimport fsmIterator from 'fsm-iterator';\nimport buildRouteMatcher from './buildRouteMatcher';\nimport createHistoryChannel from './createHistoryChannel';\n\nconst INIT = 'INIT';\nconst LISTEN = 'LISTEN';\nconst HANDLE_LOCATION = 'HANDLE_LOCATION';\n\nexport default function router(history, routes) {\n  const routeMatcher = buildRouteMatcher(routes);\n  let historyChannel = null;\n  let lastMatch = null;\n\n  function errorMessageValue(error, message) {\n    let finalMessage = `Redux Saga Router: ${message}:\\n${error.message}`;\n\n    if ('stack' in error) {\n      finalMessage += `\\n${error.stack}`;\n    }\n\n    return {\n      value: call([console, console.error], finalMessage),\n      next: LISTEN,\n    };\n  }\n\n  return fsmIterator(INIT, {\n    [INIT]: () => ({\n      value: call(createHistoryChannel, history),\n      next: LISTEN,\n    }),\n\n    [LISTEN](channel) {\n      if (channel) {\n        historyChannel = channel;\n      }\n\n      return {\n        value: take(historyChannel),\n        next: HANDLE_LOCATION,\n      };\n    },\n\n    [HANDLE_LOCATION](location, fsm) {\n      const path = location.pathname;\n      const match = routeMatcher.match(path);\n\n      if (match) {\n        lastMatch = match;\n\n        return {\n          value: call(match.action, match.params),\n          next: LISTEN,\n        };\n      }\n\n      return fsm[LISTEN]();\n    },\n\n    throw(e, fsm) {\n      switch (fsm.previousState) {\n        case HANDLE_LOCATION:\n          return errorMessageValue(e, `Unhandled ${e.name} in route \"${lastMatch.route}\"`);\n\n        case LISTEN:\n          return errorMessageValue(e, `Unexpected ${e.name} while listening for route`);\n\n        default:\n          return { done: true };\n      }\n    },\n  });\n}\n```\n","maintainers":[{"name":"elpapapollo","email":"elpapapollo@gmail.com"}],"time":{"modified":"2022-06-18T03:59:11.031Z","created":"2016-10-06T16:00:10.605Z","1.0.0":"2016-10-06T16:00:10.605Z","1.1.0":"2017-04-14T20:54:15.637Z"},"homepage":"https://github.com/jfairbank/fsm-iterator#readme","keywords":["iterator","iterable","generator","finite state machine","state machine","state","fsm"],"repository":{"type":"git","url":"git+https://github.com/jfairbank/fsm-iterator.git"},"author":{"name":"Jeremy Fairbank","email":"elpapapollo@gmail.com","url":"http://jeremyfairbank.com"},"bugs":{"url":"https://github.com/jfairbank/fsm-iterator/issues"},"license":"MIT","readmeFilename":"README.md","users":{"suissa":true,"rshaw":true}}