[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [\"es2015\", \"stage-0\", \"react\"],\n  \"plugins\": [\n    \"transform-class-properties\",\n    [\"transform-es2015-classes\", { \"loose\":true }],\n    \"transform-object-assign\",\n    [\"transform-react-jsx\", { \"pragma\":\"h\" }]\n  ]\n}\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"parser\": \"babel-eslint\",\n  \"extends\": \"eslint:recommended\",\n  \"plugins\": [\n    \"react\"\n  ],\n  \"env\": {\n    \"browser\": true,\n    \"mocha\": true,\n    \"es6\": true,\n    \"node\": true\n  },\n  \"parserOptions\": {\n    \"ecmaFeatures\": {\n      \"modules\": true,\n      \"jsx\": true\n    }\n  },\n  \"globals\": {\n    \"sinon\": true,\n    \"expect\": true\n  },\n  \"rules\": {\n    \"react/jsx-uses-react\": 2,\n    \"react/jsx-uses-vars\": 2,\n    \"no-unused-vars\": [1, { \"varsIgnorePattern\": \"^h$\" }],\n    \"no-cond-assign\": 1,\n    \"no-empty\": 0,\n    \"no-console\": 1,\n    \"semi\": 2,\n    \"camelcase\": 0,\n    \"comma-style\": 2,\n    \"comma-dangle\": [2, \"never\"],\n    \"indent\": [2, \"tab\", {\"SwitchCase\": 1}],\n    \"no-mixed-spaces-and-tabs\": [2, \"smart-tabs\"],\n    \"no-trailing-spaces\": [2, { \"skipBlankLines\": true }],\n    \"max-nested-callbacks\": [2, 5],\n    \"no-eval\": 2,\n    \"no-implied-eval\": 2,\n    \"no-new-func\": 2,\n    \"guard-for-in\": 2,\n    \"eqeqeq\": 0,\n    \"no-else-return\": 2,\n    \"no-redeclare\": 2,\n    \"no-dupe-keys\": 2,\n    \"radix\": 2,\n    \"strict\": [2, \"never\"],\n    \"no-shadow\": 0,\n    \"callback-return\": [1, [\"callback\", \"cb\", \"next\", \"done\"]],\n    \"no-delete-var\": 2,\n    \"no-undef-init\": 2,\n    \"no-shadow-restricted-names\": 2,\n    \"handle-callback-err\": 0,\n    \"no-lonely-if\": 2,\n    \"keyword-spacing\": 2,\n    \"constructor-super\": 2,\n    \"no-this-before-super\": 2,\n    \"no-dupe-class-members\": 2,\n    \"no-const-assign\": 2,\n    \"prefer-spread\": 2,\n    \"no-useless-concat\": 2,\n    \"no-var\": 2,\n    \"object-shorthand\": 2,\n    \"prefer-arrow-callback\": 2\n  }\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\ndist\nexample/public"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n  - 4\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Prateek Bhatnagar\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies 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 all\ncopies 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 FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# preact-async-route\n[![build](https://api.travis-ci.org/prateekbh/preact-async-route.svg?branch=master)](https://api.travis-ci.org/prateekbh/preact-async-route.svg?branch=master)\n[![gzip size](http://img.badgesize.io/https://unpkg.com/preact-async-route/dist/index.min.js?compression=gzip)](https://unpkg.com/preact-async-route/dist/index.min.js)\n\n## Deprecation notice\n`preact-x` supports `Lazy` component, which can be used as shown [here](https://reactjs.org/docs/code-splitting.html#reactlazy).\nPrefer using the `Lazy` component along with `Suspense` instead of this package.\n\nThis package is still useful for preact versions < 10\n\n--------------------\n\nAsync route component for [preact-router](https://github.com/developit/preact-router)\n\n`npm i -D preact-async-route`\n\npreact-async-route provides `<AsyncRoute> ` tag to load your components lazily.\n\n`<AsyncRoute> ` provides similar props to return a lazily loaded component either as a Promise resolving to the component or return the component in a callback.\n\n`<AsyncRoute> `  also has a loading props, to which you can pass a component to be shown while the component is being lazily loaded.\n\n## Version 2.0\nVersion 2.0 brings support for a new prop `component`\nin order to make usage of already imported components now preact-async-route will support 2 props\n\n1. `component` this will just take the JSX component itself and NOT the function\n2. for function calls `getComponent` is the prop\n\ncheck README :point_down:\n\n\n## Usage Example\n```js\n  import { h, render } from 'preact';\n  import Router, from 'preact-router';\n  import AsyncRoute from 'preact-async-route';\n  import Home from './Components/Home/Home.jsx';\n  import Terms from './Components/Terms/Terms.jsx';\n  import Loading from './Components/Loading/Loading.jsx';\n  /** @jsx h */\n\n  /**\n    arguments passed to getComponent:\n      url -- matched url\n      cb  -- in case you are not returning a promise\n      props -- props that component will recive upon being loaded\n  */\n  function getProfile(url, cb, props){\n  \treturn import('../component/Profile/Profile.jsx').then(module => module.default);\n  }\n\n  const Main = () => (\n  \t<Router>\n  \t\t<Home path=\"/\" />\n  \t\t<Terms path=\"/terms\" />\n  \t\t<AsyncRoute path=\"/profile/:userid\" component={Home} />\n  \t\t<AsyncRoute path=\"/friends/:userid\" getComponent={getProfile}\n            loading={()=>{return <Loading/>}} />\n  \t</Router>\n  );\n  ```\n\n### License\n\n[MIT]\n\n[MIT]: http://choosealicense.com/licenses/mit/\n"
  },
  {
    "path": "example/app.js",
    "content": "import { h, render } from 'preact';\nimport {Router, Route, route} from 'preact-router';\nimport AsyncRoute from '../src/';\nimport Home from './components/Home';\n\nfunction getProfile() {\n\treturn new Promise(resolve=>{\n\t\tsetTimeout(()=>{\n\t\t\tSystem.import('./components/Profile').then(module => {resolve(module.default);});\n\t\t},2000);\n\t});\n}\n\nfunction getTerms() {\n\treturn new Promise(resolve=>{\n\t\tsetTimeout(()=>{\n\t\t\tSystem.import('./components/Terms').then(module => {resolve(module.default);});\n\t\t},2000);\n\t});\n}\n\nrender(\n\t<Router>\n\t\t<Route path='/' component={Home}/>\n\t\t<AsyncRoute path='/profile/:pid' getComponent={getProfile} />\n\t\t<AsyncRoute path='/terms' getComponent={getTerms} loading={()=>{return (<span>loading2...</span>);}}/>\n\t</Router>,\n\tdocument.getElementById('app')\n);"
  },
  {
    "path": "example/components/Home.js",
    "content": "import {h, Component} from 'preact';\nimport {Link} from 'preact-router';\n\nexport default class Home extends Component {\n\trender() {\n\t\treturn <h1>\n\t\t\tThis is home page\n\t\t\t<Link href='/profile/prateek'>Prateek</Link>\n\t\t</h1>;\n\t}\n}"
  },
  {
    "path": "example/components/Profile.js",
    "content": "import {h, Component} from 'preact';\nimport {Link, route} from 'preact-router';\n\nexport default class Home extends Component {\n  routeToLink() {\n    route('/terms');\n  }\n\trender() {\n\t\treturn <h1>\n\t\t\tThis is Profile page of {this.props.matches.pid}\n\t\t\t<div><Link href='/profile/blah'>blah profile</Link></div>\n\t\t\t<Link href='/terms'>terms</Link>\n      <div href='/terms' onClick={this.routeToLink}>terms via route</div>\n\t\t</h1>;\n\t}\n}"
  },
  {
    "path": "example/components/Terms.js",
    "content": "import {h, Component} from 'preact';\n\nexport default class Terms extends Component {\n\trender() {\n\t\treturn <h1>This is terms and conditions page</h1>;\n\t}\n}"
  },
  {
    "path": "example/index.html",
    "content": "<html><head></head><body><div id=\"app\"></div><script type=\"text/javascript\" src=\"/public/js/app.js\"></script></body></html>"
  },
  {
    "path": "example/npm-debug.log",
    "content": "0 info it worked if it ends with ok\n1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'run', 'test' ]\n2 info using npm@4.0.5\n3 info using node@v7.4.0\n4 verbose run-script [ 'pretest', 'test', 'posttest' ]\n5 info lifecycle example@1.0.0~pretest: example@1.0.0\n6 silly lifecycle example@1.0.0~pretest: no script for pretest, continuing\n7 info lifecycle example@1.0.0~test: example@1.0.0\n8 verbose lifecycle example@1.0.0~test: unsafe-perm in lifecycle true\n9 verbose lifecycle example@1.0.0~test: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/prateekbh/projects/preact-async-route/example/node_modules/.bin:/usr/local/git/current/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin\n10 verbose lifecycle example@1.0.0~test: CWD: /Users/prateekbh/projects/preact-async-route/example\n11 silly lifecycle example@1.0.0~test: Args: [ '-c', 'echo \"Error: no test specified\" && exit 1' ]\n12 silly lifecycle example@1.0.0~test: Returned: code: 1  signal: null\n13 info lifecycle example@1.0.0~test: Failed to exec test script\n14 verbose stack Error: example@1.0.0 test: `echo \"Error: no test specified\" && exit 1`\n14 verbose stack Exit status 1\n14 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:279:16)\n14 verbose stack     at emitTwo (events.js:106:13)\n14 verbose stack     at EventEmitter.emit (events.js:191:7)\n14 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14)\n14 verbose stack     at emitTwo (events.js:106:13)\n14 verbose stack     at ChildProcess.emit (events.js:191:7)\n14 verbose stack     at maybeClose (internal/child_process.js:885:16)\n14 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)\n15 verbose pkgid example@1.0.0\n16 verbose cwd /Users/prateekbh/projects/preact-async-route/example\n17 error Darwin 16.4.0\n18 error argv \"/usr/local/bin/node\" \"/usr/local/bin/npm\" \"run\" \"test\"\n19 error node v7.4.0\n20 error npm  v4.0.5\n21 error code ELIFECYCLE\n22 error example@1.0.0 test: `echo \"Error: no test specified\" && exit 1`\n22 error Exit status 1\n23 error Failed at the example@1.0.0 test script 'echo \"Error: no test specified\" && exit 1'.\n23 error Make sure you have the latest version of node.js and npm installed.\n23 error If you do, this is most likely a problem with the example package,\n23 error not with npm itself.\n23 error Tell the author that this fails on your system:\n23 error     echo \"Error: no test specified\" && exit 1\n23 error You can get information on how to open an issue for this project with:\n23 error     npm bugs example\n23 error Or if that isn't available, you can get their info via:\n23 error     npm owner ls example\n23 error There is likely additional logging output above.\n24 verbose exit [ 1, true ]\n"
  },
  {
    "path": "example/package.json",
    "content": "{\n  \"name\": \"example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"babel-core\": \"^6.23.1\",\n    \"html-webpack-plugin\": \"^2.28.0\",\n    \"preact\": \"^7.2.0\",\n    \"preact-router\": \"^2.4.1\",\n    \"webpack\": \"^2.2.1\"\n  }\n}\n"
  },
  {
    "path": "example/webpack.config.js",
    "content": "const HtmlWebpackPlugin = require('html-webpack-plugin');\nconst config = {\n\tentry: {\n\t\tapp: './app'\n\t},\n\toutput: {\n\t\tpath: __dirname + '/public/js',\n\t\tpublicPath: '/public/js/',\n\t\tfilename: '[name].js'\n\t},\n\tmodule: {\n\t\trules: [\n\t\t\t{\n\t\t\t\tloader: 'babel-loader',\n\t\t\t\ttest: /\\.(js|jsx)$/,\n\t\t\t\texclude: /node_modules/,\n\t\t\t\toptions: {\n\t\t\t\t\tpresets: [['es2015', {\"modules\": false}]],\n\t\t\t\t\tplugins:[\n\t\t\t\t\t\t[\"transform-react-jsx\", { \"pragma\": \"h\" }]\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t]\n\t},\n\tplugins: [new HtmlWebpackPlugin({\n\t\tfilename: '../../index.html',\n\t\ttemplateContent: '<html><head></head><body><div id=\"app\"></div></body></html>'\n\t})]\n};\nmodule.exports = config;"
  },
  {
    "path": "karma.conf.js",
    "content": "module.exports = function(config) {\n\tconfig.set({\n\t\tframeworks: ['mocha', 'chai-sinon'],\n\t\treporters: ['mocha'],\n\t\tbrowsers: ['PhantomJS'],\n\n\t\tfiles: ['tests/**/*.js'],\n\n\t\tpreprocessors: {\n\t\t\t'{src,tests}/**/*.js': ['webpack', 'sourcemap']\n\t\t},\n\n\t\twebpack: {\n\t\t\tmodule: {\n\t\t\t\tloaders: [{\n\t\t\t\t\ttest: /\\.js?$/,\n\t\t\t\t\texclude: /node_modules/,\n\t\t\t\t\tloader: 'babel-loader'\n\t\t\t\t}]\n\t\t\t},\n\t\t\tresolve: {\n\t\t\t\talias: {\n\t\t\t\t\tsrc: __dirname+'/src'\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\twebpackMiddleware: {\n\t\t\tnoInfo: true\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"preact-async-route\",\n  \"version\": \"2.2.1\",\n  \"description\": \"Async route component for preact-router\",\n  \"main\": \"dist/index.min.js\",\n  \"jsnext:main\": \"src/index.js\",\n  \"types\": \"src/index.d.ts\",\n  \"scripts\": {\n    \"clean\": \"rm -rf dist/*\",\n    \"build\": \"npm-run-all clean transpile\",\n    \"transpile\": \"rollup -c rollup.config.js\",\n    \"test\": \"npm-run-all lint build test:karma test:types\",\n    \"lint\": \"eslint {src,test}\",\n    \"test:karma\": \"karma start --single-run\",\n    \"test:types\": \"tsc --project tests/ts\",\n    \"test:watch\": \"karma start\",\n    \"prepublish\": \"npm-run-all build test\",\n    \"release\": \"npm run build && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/prateekbh/preact-async-route.git\"\n  },\n  \"keywords\": [\n    \"preact\",\n    \"preact-router\",\n    \"router\"\n  ],\n  \"files\": [\n    \"src\",\n    \"dist\"\n  ],\n  \"author\": \"Prateek Bhatnagar<prateek89born@gmail.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/prateekbh/preact-async-route/issues\"\n  },\n  \"homepage\": \"https://github.com/prateekbh/preact-async-route#readme\",\n  \"devDependencies\": {\n    \"Promise\": \"^1.0.5\",\n    \"babel-cli\": \"^6.9.0\",\n    \"babel-core\": \"^6.9.1\",\n    \"babel-eslint\": \"^7.0.0\",\n    \"babel-loader\": \"^6.2.4\",\n    \"babel-plugin-transform-class-properties\": \"^6.9.1\",\n    \"babel-plugin-transform-es2015-classes\": \"^6.9.0\",\n    \"babel-plugin-transform-object-assign\": \"^6.0.0\",\n    \"babel-plugin-transform-react-jsx\": \"^6.8.0\",\n    \"babel-preset-es2015\": \"^6.9.0\",\n    \"babel-preset-react\": \"^6.5.0\",\n    \"babel-preset-stage-0\": \"^6.5.0\",\n    \"chai\": \"^3.5.0\",\n    \"eslint\": \"^3.0.0\",\n    \"eslint-plugin-react\": \"^6.10.0\",\n    \"karma\": \"^1.0.0\",\n    \"karma-chai-sinon\": \"^0.1.5\",\n    \"karma-mocha\": \"^1.0.1\",\n    \"karma-mocha-reporter\": \"^2.0.3\",\n    \"karma-phantomjs-launcher\": \"^1.0.0\",\n    \"karma-sourcemap-loader\": \"^0.3.7\",\n    \"karma-webpack\": \"^2.0.1\",\n    \"mkdirp\": \"^0.5.1\",\n    \"mocha\": \"^3.2.0\",\n    \"npm-run-all\": \"^3.0.0\",\n    \"preact\": \"*\",\n    \"preact-router\": \"*\",\n    \"rollup\": \"^0.41.4\",\n    \"rollup-plugin-babel\": \"^2.7.1\",\n    \"rollup-plugin-minify\": \"^1.0.3\",\n    \"sinon\": \"^1.17.4\",\n    \"sinon-chai\": \"^2.8.0\",\n    \"typescript\": \"^2.7.2\",\n    \"uglify-js\": \"^2.6.1\",\n    \"webpack\": \"^2.2.1\"\n  },\n  \"peerDependencies\": {\n    \"preact\": \"*\",\n    \"preact-router\": \"*\"\n  }\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import fs from 'fs';\nimport babel from 'rollup-plugin-babel';\nimport minify from 'rollup-plugin-minify';\nconst packageDetils = require(__dirname+'/package.json');\nvar babelRc = JSON.parse(fs.readFileSync('.babelrc','utf8')); // eslint-disable-line\n\nexport default {\n\tentry: 'src/index.js',\n\tformat: 'umd',\n\tsourceMap: true,\n\tmoduleName: packageDetils.name,\n\tdest: 'dist/index.js',\n\tplugins: [\n\t\tbabel({\n\t\t\tbabelrc: false,\n\t\t\tpresets: [\n\t\t\t\t['es2015', { loose:true, modules:false }]\n\t\t\t].concat(babelRc.presets.slice(1)),\n\t\t\tplugins: babelRc.plugins,\n\t\t\texclude: 'node_modules/**'\n\t\t}),\n\t\tminify({umd: 'dist/index.min.js'})\n\t]\n};\n"
  },
  {
    "path": "src/index.d.ts",
    "content": "import { Component, FunctionalComponent } from 'preact';\n\ninterface IAsyncRouteProps {\n    path: string;\n    component?: any;\n    getComponent?: (\n        this: AsyncRoute,\n        url: string,\n        callback: (component: any) => void,\n        props: any\n    ) => Promise<any> | void;\n    loading?: () => JSX.Element;\n    [key:string]: any;\n}\n\nexport default class AsyncRoute extends Component<IAsyncRouteProps, {}> {\n    public render(): JSX.Element | null;\n}\n"
  },
  {
    "path": "src/index.js",
    "content": "import { h, Component } from 'preact';\n\nclass AsyncRoute extends Component {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.state = {\n\t\t\tcomponentData: null\n\t\t};\n\t}\n\tloadComponent(){\n\t\tif (this.props.component) {\n\t\t\treturn this.setState({\n\t\t\t\tcomponentData: this.props.component\n\t\t\t});\n\t\t}\n\t\tconst componentData = this.props.getComponent(this.props.url, ({component}) => {\n\t\t\t// Named param for making callback future proof\n\t\t\tif (component) {\n\t\t\t\tthis.setState({\n\t\t\t\t\tcomponentData: component\n\t\t\t\t});\n\t\t\t}\n\t\t}, Object.assign({}, this.props, this.props.matches));\n\n\t\t// In case returned value was a promise\n\t\tif (componentData && componentData.then) {\n\t\t\t// IIFE to check if a later ending promise was creating a race condition\n\t\t\t// Check test case for more info\n\t\t\t((url)=>{\n\t\t\t\tcomponentData.then(component => {\n\t\t\t\t\tif (url !== this.props.url) {\n\t\t\t\t\t\tthis.setState({componentData: null}, () => {\n\t\t\t\t\t\t\tthis.loadComponent();\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tthis.setState({\n\t\t\t\t\t\tcomponentData: component\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t})(this.props.url);\n\t\t}\n\t}\n\tcomponentWillReceiveProps(nextProps){\n\t\tif (this.props.path && this.props.path !== nextProps.path) {\n\t\t\tthis.setState({\n\t\t\t\tcomponentData: null\n\t\t\t}, ()=>{\n\t\t\t\tthis.loadComponent();\n\t\t\t});\n\t\t}\n\t}\n\tcomponentWillMount(){\n\t\tthis.loadComponent();\n\t}\n\trender(){\n\t\tif (this.state.componentData) {\n\t\t\treturn h(this.state.componentData, this.props);\n\t\t} else if (this.props.loading) {\n\t\t\tconst loadingComponent = this.props.loading();\n\t\t\treturn loadingComponent;\n\t\t}\n\t\treturn null;\n\t}\n}\n\nexport default AsyncRoute;\n"
  },
  {
    "path": "tests/index.js",
    "content": "import { h, render, Component, options } from 'preact';\nimport Router,{route} from 'preact-router';\nimport AsyncRoute from 'src/index';\nimport Promise from 'Promise';\n\ndescribe('Async Route', () => {\n\toptions.syncComponentUpdates = false;\n\toptions.debounceRendering = f => f();\n\tclass SampleTag extends Component {\n\t\trender(){\n\t\t\treturn (<h1>hi</h1>);\n\t\t}\n\t}\n\tclass ParameterizedSampleTag extends Component {\n\t\trender(){\n\t\t\treturn (<h1>hi - {this.props.matches.pid}</h1>);\n\t\t}\n\t}\n\n\tit('should call the given function on mount', () => {\n\t\tlet getComponent = sinon.spy();\n\t\trender(<AsyncRoute getComponent={getComponent} />, document.createElement('div'));\n\t\texpect(getComponent).called;\n\t});\n\n\tit('should render component when returned from the callback', () => {\n\t\tlet containerTag = document.createElement('div');\n\t\tlet getComponent = function(url, cb) {\n\t\t\tcb({component: SampleTag});\n\t\t};\n\t\trender(<AsyncRoute getComponent={getComponent} />, containerTag);\n\t\texpect(containerTag.innerHTML).equal('<h1>hi</h1>');\n\t});\n\n\tit('should render component when resolved through a promise from a function', () => {\n\t\tlet containerTag = document.createElement('div');\n\t\tconst startTime = Date.now();\n\t\tconst componentPromise = new Promise(resolve=>{\n\t\t\tsetTimeout(()=>{\n\t\t\t\tresolve(SampleTag);\n\t\t\t},800);\n\t\t});\n\n\t\tlet getComponent = function() {\n\t\t\treturn componentPromise;\n\t\t};\n\n\t\trender(<AsyncRoute getComponent={getComponent} />, containerTag);\n\n\t\tcomponentPromise.then(()=>{\n\t\t\tconst endTime = Date.now();\n\t\t\texpect(endTime - startTime).to.be.greaterThan(800);\n\t\t\texpect(containerTag.innerHTML).equal('<h1>hi</h1>');\n\t\t});\n\t});\n\n\tit('should render loading component while component is not resolved', () => {\n\t\tlet containerTag = document.createElement('div');\n\t\tconst startTime = Date.now();\n\t\tconst componentPromise = new Promise(resolve=>{\n\t\t\tsetTimeout(()=>{\n\t\t\t\tresolve(SampleTag);\n\t\t\t},800);\n\t\t});\n\n\t\tlet getComponent = function() {\n\t\t\treturn componentPromise;\n\t\t};\n\n\t\trender(<AsyncRoute loading={() => <span>loading...</span>} getComponent={getComponent} />, containerTag);\n\n\t\texpect(containerTag.innerHTML).equal('<span>loading...</span>');\n\n\t\tcomponentPromise.then(()=>{\n\t\t\tconst endTime = Date.now();\n\t\t\texpect(endTime - startTime).to.be.greaterThan(800);\n\t\t\texpect(containerTag.innerHTML).equal('<h1>hi</h1>');\n\t\t});\n\t});\n\n\tit('should get all props', () => {\n\t\tlet containerTag = document.createElement('div');\n\t\tclass PropsTag extends Component {\n\t\t\trender(){\n\t\t\t\treturn (<h1>hi - {this.props.matches.pid} - {this.props.sequence}</h1>);\n\t\t\t}\n\t\t}\n\t\tlet getComponent = function(url, cb) {\n\t\t\tcb({component: PropsTag});\n\t\t};\n\t\trender(<Router><AsyncRoute path='/profile/:pid' sequence=\"1\" getComponent={getComponent} /></Router>, containerTag);\n\t\troute('/profile/Prateek');\n\t\texpect(containerTag.innerHTML).equal('<h1>hi - Prateek - 1</h1>');\n\t\troute('/profile/Jason');\n\t\texpect(containerTag.innerHTML).equal('<h1>hi - Jason - 1</h1>');\n\t});\n\n\tit('should update on url change for same component', () => {\n\t\tlet containerTag = document.createElement('div');\n\t\tlet getComponent = function(url, cb) {\n\t\t\tcb({component: ParameterizedSampleTag});\n\t\t};\n\t\trender(<Router><AsyncRoute path='/profile/:pid' getComponent={getComponent} /></Router>, containerTag);\n\t\troute('/profile/Prateek');\n\t\texpect(containerTag.innerHTML).equal('<h1>hi - Prateek</h1>');\n\t\troute('/profile/Jason');\n\t\texpect(containerTag.innerHTML).equal('<h1>hi - Jason</h1>');\n\t});\n\n\tit('should mount correct component in case of race conditions', (done) => {\n\t\tlet containerTag = document.createElement('div');\n\t\tlet getParameterizedComponent = function(url, cb) {\n\t\t\treturn new Promise(resolve=>{\n\t\t\t\tsetTimeout(()=>{\n\t\t\t\t\tresolve(ParameterizedSampleTag);\n\t\t\t\t},200);\n\t\t\t});\n\t\t};\n\t\tlet getComponent = function(url, cb) {\n\t\t\treturn new Promise(resolve=>{\n\t\t\t\tsetTimeout(()=>{\n\t\t\t\t\tresolve(SampleTag);\n\t\t\t\t},1);\n\t\t\t});\n\t\t};\n\t\trender(<Router><AsyncRoute path='/profile/:pid' getComponent={getParameterizedComponent} /><AsyncRoute path='/' getComponent={getComponent} /></Router>, containerTag);\n\t\troute('/profile/Prateek');\n\t\troute('/');\n\t\tsetTimeout(()=>{\n\t\t\texpect(containerTag.innerHTML).equal('<h1>hi</h1>');\n\t\t\tdone();\n\t\t},400);\n\t});\n\n\tit('should pass matches to getComponent', () => {\n\t\tlet containerTag = document.createElement('div');\n\t\tlet controlMatch = Math.random().toString();\n\t\tlet controlProp = Math.random();\n\t\tlet recivedMatch;\n\t\tlet recivedProp;\n\n\t\tlet getComponent = function(url, cb, props) {\n\t\t\trecivedMatch = props.pid;\n\t\t\trecivedProp = props.sequence;\n\t\t\tcb({component: props => null});\n\t\t};\n\t\trender(<Router><AsyncRoute path='/profile/:pid' sequence={controlProp} getComponent={getComponent} /></Router>, containerTag);\n\t\troute('/profile/' + controlMatch);\n\t\texpect(recivedMatch).equal(controlMatch);\n\t\texpect(recivedProp).equal(recivedProp);\n\t})\n});\n"
  },
  {
    "path": "tests/ts/index.tsx",
    "content": "import { h, render, Component } from 'preact';\nimport Router from 'preact-router';\nimport AsyncRoute from '../../';\n\n/**\n * This dummy component is used to catch TypeScript\n * type issues via the TypeScript compiler.\n */\n\nfunction componentFetcher(url: string, cb: (c: any) => void, props: any): Promise<any> | void {}\nfunction loadingAnimation(): JSX.Element | any {\n    return <div></div>;\n}\ntype LabelProps = {\n    value: string\n}\n\nfunction labelize({props}: { props: LabelProps }): JSX.Element {\n    return <label>{props.value}</label>\n}\nexport class Index extends Component<{}, {}> {\n    public render(): JSX.Element {\n        return <Router>\n            <AsyncRoute path=\"/\" component={Router} />\n            <AsyncRoute path=\"/\" getComponent={componentFetcher} />\n            <AsyncRoute path=\"/\" getComponent={componentFetcher} loading={loadingAnimation} />\n            <AsyncRoute path=\"/\" component={labelize} value=\"Label me!\" />\n        </Router>;\n    }\n}\n"
  },
  {
    "path": "tests/ts/tsconfig.json",
    "content": "{\n\t\"compilerOptions\": {\n\t\t\"module\": \"commonjs\",\n\t\t\"lib\": [\n\t\t\t\"es6\",\n\t\t\t\"dom\"\n\t\t],\n\t\t\"noImplicitAny\": true,\n\t\t\"noImplicitThis\": true,\n\t\t\"strictNullChecks\": false,\n\t\t\"typeRoots\": [\n\t\t\t\"../../\"\n\t\t],\n\t\t\"types\": [],\n\t\t\"noEmit\": true,\n\t\t\"forceConsistentCasingInFileNames\": true,\n\t\t\"jsx\": \"react\",\n\t\t\"jsxFactory\": \"h\"\n\t},\n\t\"files\": [\n\t\t\"index.tsx\",\n\t\t\"../../src/index.d.ts\"\n\t]\n}"
  }
]