Repository: prateekbh/preact-async-route
Branch: master
Commit: a06eb0792cb7
Files: 22
Total size: 22.2 KB
Directory structure:
gitextract_n6wo97o8/
├── .babelrc
├── .eslintrc
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── example/
│ ├── app.js
│ ├── components/
│ │ ├── Home.js
│ │ ├── Profile.js
│ │ └── Terms.js
│ ├── index.html
│ ├── npm-debug.log
│ ├── package.json
│ └── webpack.config.js
├── karma.conf.js
├── package.json
├── rollup.config.js
├── src/
│ ├── index.d.ts
│ └── index.js
└── tests/
├── index.js
└── ts/
├── index.tsx
└── tsconfig.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"presets": ["es2015", "stage-0", "react"],
"plugins": [
"transform-class-properties",
["transform-es2015-classes", { "loose":true }],
"transform-object-assign",
["transform-react-jsx", { "pragma":"h" }]
]
}
================================================
FILE: .eslintrc
================================================
{
"parser": "babel-eslint",
"extends": "eslint:recommended",
"plugins": [
"react"
],
"env": {
"browser": true,
"mocha": true,
"es6": true,
"node": true
},
"parserOptions": {
"ecmaFeatures": {
"modules": true,
"jsx": true
}
},
"globals": {
"sinon": true,
"expect": true
},
"rules": {
"react/jsx-uses-react": 2,
"react/jsx-uses-vars": 2,
"no-unused-vars": [1, { "varsIgnorePattern": "^h$" }],
"no-cond-assign": 1,
"no-empty": 0,
"no-console": 1,
"semi": 2,
"camelcase": 0,
"comma-style": 2,
"comma-dangle": [2, "never"],
"indent": [2, "tab", {"SwitchCase": 1}],
"no-mixed-spaces-and-tabs": [2, "smart-tabs"],
"no-trailing-spaces": [2, { "skipBlankLines": true }],
"max-nested-callbacks": [2, 5],
"no-eval": 2,
"no-implied-eval": 2,
"no-new-func": 2,
"guard-for-in": 2,
"eqeqeq": 0,
"no-else-return": 2,
"no-redeclare": 2,
"no-dupe-keys": 2,
"radix": 2,
"strict": [2, "never"],
"no-shadow": 0,
"callback-return": [1, ["callback", "cb", "next", "done"]],
"no-delete-var": 2,
"no-undef-init": 2,
"no-shadow-restricted-names": 2,
"handle-callback-err": 0,
"no-lonely-if": 2,
"keyword-spacing": 2,
"constructor-super": 2,
"no-this-before-super": 2,
"no-dupe-class-members": 2,
"no-const-assign": 2,
"prefer-spread": 2,
"no-useless-concat": 2,
"no-var": 2,
"object-shorthand": 2,
"prefer-arrow-callback": 2
}
}
================================================
FILE: .gitignore
================================================
node_modules
dist
example/public
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- 4
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Prateek Bhatnagar
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# preact-async-route
[](https://api.travis-ci.org/prateekbh/preact-async-route.svg?branch=master)
[](https://unpkg.com/preact-async-route/dist/index.min.js)
## Deprecation notice
`preact-x` supports `Lazy` component, which can be used as shown [here](https://reactjs.org/docs/code-splitting.html#reactlazy).
Prefer using the `Lazy` component along with `Suspense` instead of this package.
This package is still useful for preact versions < 10
--------------------
Async route component for [preact-router](https://github.com/developit/preact-router)
`npm i -D preact-async-route`
preact-async-route provides `<AsyncRoute> ` tag to load your components lazily.
`<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.
`<AsyncRoute> ` also has a loading props, to which you can pass a component to be shown while the component is being lazily loaded.
## Version 2.0
Version 2.0 brings support for a new prop `component`
in order to make usage of already imported components now preact-async-route will support 2 props
1. `component` this will just take the JSX component itself and NOT the function
2. for function calls `getComponent` is the prop
check README :point_down:
## Usage Example
```js
import { h, render } from 'preact';
import Router, from 'preact-router';
import AsyncRoute from 'preact-async-route';
import Home from './Components/Home/Home.jsx';
import Terms from './Components/Terms/Terms.jsx';
import Loading from './Components/Loading/Loading.jsx';
/** @jsx h */
/**
arguments passed to getComponent:
url -- matched url
cb -- in case you are not returning a promise
props -- props that component will recive upon being loaded
*/
function getProfile(url, cb, props){
return import('../component/Profile/Profile.jsx').then(module => module.default);
}
const Main = () => (
<Router>
<Home path="/" />
<Terms path="/terms" />
<AsyncRoute path="/profile/:userid" component={Home} />
<AsyncRoute path="/friends/:userid" getComponent={getProfile}
loading={()=>{return <Loading/>}} />
</Router>
);
```
### License
[MIT]
[MIT]: http://choosealicense.com/licenses/mit/
================================================
FILE: example/app.js
================================================
import { h, render } from 'preact';
import {Router, Route, route} from 'preact-router';
import AsyncRoute from '../src/';
import Home from './components/Home';
function getProfile() {
return new Promise(resolve=>{
setTimeout(()=>{
System.import('./components/Profile').then(module => {resolve(module.default);});
},2000);
});
}
function getTerms() {
return new Promise(resolve=>{
setTimeout(()=>{
System.import('./components/Terms').then(module => {resolve(module.default);});
},2000);
});
}
render(
<Router>
<Route path='/' component={Home}/>
<AsyncRoute path='/profile/:pid' getComponent={getProfile} />
<AsyncRoute path='/terms' getComponent={getTerms} loading={()=>{return (<span>loading2...</span>);}}/>
</Router>,
document.getElementById('app')
);
================================================
FILE: example/components/Home.js
================================================
import {h, Component} from 'preact';
import {Link} from 'preact-router';
export default class Home extends Component {
render() {
return <h1>
This is home page
<Link href='/profile/prateek'>Prateek</Link>
</h1>;
}
}
================================================
FILE: example/components/Profile.js
================================================
import {h, Component} from 'preact';
import {Link, route} from 'preact-router';
export default class Home extends Component {
routeToLink() {
route('/terms');
}
render() {
return <h1>
This is Profile page of {this.props.matches.pid}
<div><Link href='/profile/blah'>blah profile</Link></div>
<Link href='/terms'>terms</Link>
<div href='/terms' onClick={this.routeToLink}>terms via route</div>
</h1>;
}
}
================================================
FILE: example/components/Terms.js
================================================
import {h, Component} from 'preact';
export default class Terms extends Component {
render() {
return <h1>This is terms and conditions page</h1>;
}
}
================================================
FILE: example/index.html
================================================
<html><head></head><body><div id="app"></div><script type="text/javascript" src="/public/js/app.js"></script></body></html>
================================================
FILE: example/npm-debug.log
================================================
0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'run', 'test' ]
2 info using npm@4.0.5
3 info using node@v7.4.0
4 verbose run-script [ 'pretest', 'test', 'posttest' ]
5 info lifecycle example@1.0.0~pretest: example@1.0.0
6 silly lifecycle example@1.0.0~pretest: no script for pretest, continuing
7 info lifecycle example@1.0.0~test: example@1.0.0
8 verbose lifecycle example@1.0.0~test: unsafe-perm in lifecycle true
9 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
10 verbose lifecycle example@1.0.0~test: CWD: /Users/prateekbh/projects/preact-async-route/example
11 silly lifecycle example@1.0.0~test: Args: [ '-c', 'echo "Error: no test specified" && exit 1' ]
12 silly lifecycle example@1.0.0~test: Returned: code: 1 signal: null
13 info lifecycle example@1.0.0~test: Failed to exec test script
14 verbose stack Error: example@1.0.0 test: `echo "Error: no test specified" && exit 1`
14 verbose stack Exit status 1
14 verbose stack at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:279:16)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at EventEmitter.emit (events.js:191:7)
14 verbose stack at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14)
14 verbose stack at emitTwo (events.js:106:13)
14 verbose stack at ChildProcess.emit (events.js:191:7)
14 verbose stack at maybeClose (internal/child_process.js:885:16)
14 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
15 verbose pkgid example@1.0.0
16 verbose cwd /Users/prateekbh/projects/preact-async-route/example
17 error Darwin 16.4.0
18 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "test"
19 error node v7.4.0
20 error npm v4.0.5
21 error code ELIFECYCLE
22 error example@1.0.0 test: `echo "Error: no test specified" && exit 1`
22 error Exit status 1
23 error Failed at the example@1.0.0 test script 'echo "Error: no test specified" && exit 1'.
23 error Make sure you have the latest version of node.js and npm installed.
23 error If you do, this is most likely a problem with the example package,
23 error not with npm itself.
23 error Tell the author that this fails on your system:
23 error echo "Error: no test specified" && exit 1
23 error You can get information on how to open an issue for this project with:
23 error npm bugs example
23 error Or if that isn't available, you can get their info via:
23 error npm owner ls example
23 error There is likely additional logging output above.
24 verbose exit [ 1, true ]
================================================
FILE: example/package.json
================================================
{
"name": "example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.23.1",
"html-webpack-plugin": "^2.28.0",
"preact": "^7.2.0",
"preact-router": "^2.4.1",
"webpack": "^2.2.1"
}
}
================================================
FILE: example/webpack.config.js
================================================
const HtmlWebpackPlugin = require('html-webpack-plugin');
const config = {
entry: {
app: './app'
},
output: {
path: __dirname + '/public/js',
publicPath: '/public/js/',
filename: '[name].js'
},
module: {
rules: [
{
loader: 'babel-loader',
test: /\.(js|jsx)$/,
exclude: /node_modules/,
options: {
presets: [['es2015', {"modules": false}]],
plugins:[
["transform-react-jsx", { "pragma": "h" }]
]
}
}
]
},
plugins: [new HtmlWebpackPlugin({
filename: '../../index.html',
templateContent: '<html><head></head><body><div id="app"></div></body></html>'
})]
};
module.exports = config;
================================================
FILE: karma.conf.js
================================================
module.exports = function(config) {
config.set({
frameworks: ['mocha', 'chai-sinon'],
reporters: ['mocha'],
browsers: ['PhantomJS'],
files: ['tests/**/*.js'],
preprocessors: {
'{src,tests}/**/*.js': ['webpack', 'sourcemap']
},
webpack: {
module: {
loaders: [{
test: /\.js?$/,
exclude: /node_modules/,
loader: 'babel-loader'
}]
},
resolve: {
alias: {
src: __dirname+'/src'
}
}
},
webpackMiddleware: {
noInfo: true
}
});
};
================================================
FILE: package.json
================================================
{
"name": "preact-async-route",
"version": "2.2.1",
"description": "Async route component for preact-router",
"main": "dist/index.min.js",
"jsnext:main": "src/index.js",
"types": "src/index.d.ts",
"scripts": {
"clean": "rm -rf dist/*",
"build": "npm-run-all clean transpile",
"transpile": "rollup -c rollup.config.js",
"test": "npm-run-all lint build test:karma test:types",
"lint": "eslint {src,test}",
"test:karma": "karma start --single-run",
"test:types": "tsc --project tests/ts",
"test:watch": "karma start",
"prepublish": "npm-run-all build test",
"release": "npm run build && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish"
},
"repository": {
"type": "git",
"url": "git+https://github.com/prateekbh/preact-async-route.git"
},
"keywords": [
"preact",
"preact-router",
"router"
],
"files": [
"src",
"dist"
],
"author": "Prateek Bhatnagar<prateek89born@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/prateekbh/preact-async-route/issues"
},
"homepage": "https://github.com/prateekbh/preact-async-route#readme",
"devDependencies": {
"Promise": "^1.0.5",
"babel-cli": "^6.9.0",
"babel-core": "^6.9.1",
"babel-eslint": "^7.0.0",
"babel-loader": "^6.2.4",
"babel-plugin-transform-class-properties": "^6.9.1",
"babel-plugin-transform-es2015-classes": "^6.9.0",
"babel-plugin-transform-object-assign": "^6.0.0",
"babel-plugin-transform-react-jsx": "^6.8.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-react": "^6.5.0",
"babel-preset-stage-0": "^6.5.0",
"chai": "^3.5.0",
"eslint": "^3.0.0",
"eslint-plugin-react": "^6.10.0",
"karma": "^1.0.0",
"karma-chai-sinon": "^0.1.5",
"karma-mocha": "^1.0.1",
"karma-mocha-reporter": "^2.0.3",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.1",
"mkdirp": "^0.5.1",
"mocha": "^3.2.0",
"npm-run-all": "^3.0.0",
"preact": "*",
"preact-router": "*",
"rollup": "^0.41.4",
"rollup-plugin-babel": "^2.7.1",
"rollup-plugin-minify": "^1.0.3",
"sinon": "^1.17.4",
"sinon-chai": "^2.8.0",
"typescript": "^2.7.2",
"uglify-js": "^2.6.1",
"webpack": "^2.2.1"
},
"peerDependencies": {
"preact": "*",
"preact-router": "*"
}
}
================================================
FILE: rollup.config.js
================================================
import fs from 'fs';
import babel from 'rollup-plugin-babel';
import minify from 'rollup-plugin-minify';
const packageDetils = require(__dirname+'/package.json');
var babelRc = JSON.parse(fs.readFileSync('.babelrc','utf8')); // eslint-disable-line
export default {
entry: 'src/index.js',
format: 'umd',
sourceMap: true,
moduleName: packageDetils.name,
dest: 'dist/index.js',
plugins: [
babel({
babelrc: false,
presets: [
['es2015', { loose:true, modules:false }]
].concat(babelRc.presets.slice(1)),
plugins: babelRc.plugins,
exclude: 'node_modules/**'
}),
minify({umd: 'dist/index.min.js'})
]
};
================================================
FILE: src/index.d.ts
================================================
import { Component, FunctionalComponent } from 'preact';
interface IAsyncRouteProps {
path: string;
component?: any;
getComponent?: (
this: AsyncRoute,
url: string,
callback: (component: any) => void,
props: any
) => Promise<any> | void;
loading?: () => JSX.Element;
[key:string]: any;
}
export default class AsyncRoute extends Component<IAsyncRouteProps, {}> {
public render(): JSX.Element | null;
}
================================================
FILE: src/index.js
================================================
import { h, Component } from 'preact';
class AsyncRoute extends Component {
constructor() {
super();
this.state = {
componentData: null
};
}
loadComponent(){
if (this.props.component) {
return this.setState({
componentData: this.props.component
});
}
const componentData = this.props.getComponent(this.props.url, ({component}) => {
// Named param for making callback future proof
if (component) {
this.setState({
componentData: component
});
}
}, Object.assign({}, this.props, this.props.matches));
// In case returned value was a promise
if (componentData && componentData.then) {
// IIFE to check if a later ending promise was creating a race condition
// Check test case for more info
((url)=>{
componentData.then(component => {
if (url !== this.props.url) {
this.setState({componentData: null}, () => {
this.loadComponent();
});
return;
}
this.setState({
componentData: component
});
});
})(this.props.url);
}
}
componentWillReceiveProps(nextProps){
if (this.props.path && this.props.path !== nextProps.path) {
this.setState({
componentData: null
}, ()=>{
this.loadComponent();
});
}
}
componentWillMount(){
this.loadComponent();
}
render(){
if (this.state.componentData) {
return h(this.state.componentData, this.props);
} else if (this.props.loading) {
const loadingComponent = this.props.loading();
return loadingComponent;
}
return null;
}
}
export default AsyncRoute;
================================================
FILE: tests/index.js
================================================
import { h, render, Component, options } from 'preact';
import Router,{route} from 'preact-router';
import AsyncRoute from 'src/index';
import Promise from 'Promise';
describe('Async Route', () => {
options.syncComponentUpdates = false;
options.debounceRendering = f => f();
class SampleTag extends Component {
render(){
return (<h1>hi</h1>);
}
}
class ParameterizedSampleTag extends Component {
render(){
return (<h1>hi - {this.props.matches.pid}</h1>);
}
}
it('should call the given function on mount', () => {
let getComponent = sinon.spy();
render(<AsyncRoute getComponent={getComponent} />, document.createElement('div'));
expect(getComponent).called;
});
it('should render component when returned from the callback', () => {
let containerTag = document.createElement('div');
let getComponent = function(url, cb) {
cb({component: SampleTag});
};
render(<AsyncRoute getComponent={getComponent} />, containerTag);
expect(containerTag.innerHTML).equal('<h1>hi</h1>');
});
it('should render component when resolved through a promise from a function', () => {
let containerTag = document.createElement('div');
const startTime = Date.now();
const componentPromise = new Promise(resolve=>{
setTimeout(()=>{
resolve(SampleTag);
},800);
});
let getComponent = function() {
return componentPromise;
};
render(<AsyncRoute getComponent={getComponent} />, containerTag);
componentPromise.then(()=>{
const endTime = Date.now();
expect(endTime - startTime).to.be.greaterThan(800);
expect(containerTag.innerHTML).equal('<h1>hi</h1>');
});
});
it('should render loading component while component is not resolved', () => {
let containerTag = document.createElement('div');
const startTime = Date.now();
const componentPromise = new Promise(resolve=>{
setTimeout(()=>{
resolve(SampleTag);
},800);
});
let getComponent = function() {
return componentPromise;
};
render(<AsyncRoute loading={() => <span>loading...</span>} getComponent={getComponent} />, containerTag);
expect(containerTag.innerHTML).equal('<span>loading...</span>');
componentPromise.then(()=>{
const endTime = Date.now();
expect(endTime - startTime).to.be.greaterThan(800);
expect(containerTag.innerHTML).equal('<h1>hi</h1>');
});
});
it('should get all props', () => {
let containerTag = document.createElement('div');
class PropsTag extends Component {
render(){
return (<h1>hi - {this.props.matches.pid} - {this.props.sequence}</h1>);
}
}
let getComponent = function(url, cb) {
cb({component: PropsTag});
};
render(<Router><AsyncRoute path='/profile/:pid' sequence="1" getComponent={getComponent} /></Router>, containerTag);
route('/profile/Prateek');
expect(containerTag.innerHTML).equal('<h1>hi - Prateek - 1</h1>');
route('/profile/Jason');
expect(containerTag.innerHTML).equal('<h1>hi - Jason - 1</h1>');
});
it('should update on url change for same component', () => {
let containerTag = document.createElement('div');
let getComponent = function(url, cb) {
cb({component: ParameterizedSampleTag});
};
render(<Router><AsyncRoute path='/profile/:pid' getComponent={getComponent} /></Router>, containerTag);
route('/profile/Prateek');
expect(containerTag.innerHTML).equal('<h1>hi - Prateek</h1>');
route('/profile/Jason');
expect(containerTag.innerHTML).equal('<h1>hi - Jason</h1>');
});
it('should mount correct component in case of race conditions', (done) => {
let containerTag = document.createElement('div');
let getParameterizedComponent = function(url, cb) {
return new Promise(resolve=>{
setTimeout(()=>{
resolve(ParameterizedSampleTag);
},200);
});
};
let getComponent = function(url, cb) {
return new Promise(resolve=>{
setTimeout(()=>{
resolve(SampleTag);
},1);
});
};
render(<Router><AsyncRoute path='/profile/:pid' getComponent={getParameterizedComponent} /><AsyncRoute path='/' getComponent={getComponent} /></Router>, containerTag);
route('/profile/Prateek');
route('/');
setTimeout(()=>{
expect(containerTag.innerHTML).equal('<h1>hi</h1>');
done();
},400);
});
it('should pass matches to getComponent', () => {
let containerTag = document.createElement('div');
let controlMatch = Math.random().toString();
let controlProp = Math.random();
let recivedMatch;
let recivedProp;
let getComponent = function(url, cb, props) {
recivedMatch = props.pid;
recivedProp = props.sequence;
cb({component: props => null});
};
render(<Router><AsyncRoute path='/profile/:pid' sequence={controlProp} getComponent={getComponent} /></Router>, containerTag);
route('/profile/' + controlMatch);
expect(recivedMatch).equal(controlMatch);
expect(recivedProp).equal(recivedProp);
})
});
================================================
FILE: tests/ts/index.tsx
================================================
import { h, render, Component } from 'preact';
import Router from 'preact-router';
import AsyncRoute from '../../';
/**
* This dummy component is used to catch TypeScript
* type issues via the TypeScript compiler.
*/
function componentFetcher(url: string, cb: (c: any) => void, props: any): Promise<any> | void {}
function loadingAnimation(): JSX.Element | any {
return <div></div>;
}
type LabelProps = {
value: string
}
function labelize({props}: { props: LabelProps }): JSX.Element {
return <label>{props.value}</label>
}
export class Index extends Component<{}, {}> {
public render(): JSX.Element {
return <Router>
<AsyncRoute path="/" component={Router} />
<AsyncRoute path="/" getComponent={componentFetcher} />
<AsyncRoute path="/" getComponent={componentFetcher} loading={loadingAnimation} />
<AsyncRoute path="/" component={labelize} value="Label me!" />
</Router>;
}
}
================================================
FILE: tests/ts/tsconfig.json
================================================
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6",
"dom"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"typeRoots": [
"../../"
],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react",
"jsxFactory": "h"
},
"files": [
"index.tsx",
"../../src/index.d.ts"
]
}
gitextract_n6wo97o8/
├── .babelrc
├── .eslintrc
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── example/
│ ├── app.js
│ ├── components/
│ │ ├── Home.js
│ │ ├── Profile.js
│ │ └── Terms.js
│ ├── index.html
│ ├── npm-debug.log
│ ├── package.json
│ └── webpack.config.js
├── karma.conf.js
├── package.json
├── rollup.config.js
├── src/
│ ├── index.d.ts
│ └── index.js
└── tests/
├── index.js
└── ts/
├── index.tsx
└── tsconfig.json
SYMBOL INDEX (29 symbols across 8 files)
FILE: example/app.js
function getProfile (line 6) | function getProfile() {
function getTerms (line 14) | function getTerms() {
FILE: example/components/Home.js
class Home (line 4) | class Home extends Component {
method render (line 5) | render() {
FILE: example/components/Profile.js
class Home (line 4) | class Home extends Component {
method routeToLink (line 5) | routeToLink() {
method render (line 8) | render() {
FILE: example/components/Terms.js
class Terms (line 3) | class Terms extends Component {
method render (line 4) | render() {
FILE: src/index.d.ts
type IAsyncRouteProps (line 3) | interface IAsyncRouteProps {
class AsyncRoute (line 16) | class AsyncRoute extends Component<IAsyncRouteProps, {}> {
FILE: src/index.js
class AsyncRoute (line 3) | class AsyncRoute extends Component {
method constructor (line 4) | constructor() {
method loadComponent (line 10) | loadComponent(){
method componentWillReceiveProps (line 44) | componentWillReceiveProps(nextProps){
method componentWillMount (line 53) | componentWillMount(){
method render (line 56) | render(){
FILE: tests/index.js
class SampleTag (line 9) | class SampleTag extends Component {
method render (line 10) | render(){
class ParameterizedSampleTag (line 14) | class ParameterizedSampleTag extends Component {
method render (line 15) | render(){
class PropsTag (line 83) | class PropsTag extends Component {
method render (line 84) | render(){
FILE: tests/ts/index.tsx
function componentFetcher (line 10) | function componentFetcher(url: string, cb: (c: any) => void, props: any)...
function loadingAnimation (line 11) | function loadingAnimation(): JSX.Element | any {
type LabelProps (line 14) | type LabelProps = {
function labelize (line 18) | function labelize({props}: { props: LabelProps }): JSX.Element {
class Index (line 21) | class Index extends Component<{}, {}> {
method render (line 22) | public render(): JSX.Element {
Condensed preview — 22 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (26K chars).
[
{
"path": ".babelrc",
"chars": 231,
"preview": "{\n \"presets\": [\"es2015\", \"stage-0\", \"react\"],\n \"plugins\": [\n \"transform-class-properties\",\n [\"transform-es2015-c"
},
{
"path": ".eslintrc",
"chars": 1539,
"preview": "{\n \"parser\": \"babel-eslint\",\n \"extends\": \"eslint:recommended\",\n \"plugins\": [\n \"react\"\n ],\n \"env\": {\n \"browser"
},
{
"path": ".gitignore",
"chars": 32,
"preview": "node_modules\ndist\nexample/public"
},
{
"path": ".travis.yml",
"chars": 33,
"preview": "language: node_js\nnode_js:\n - 4\n"
},
{
"path": "LICENSE",
"chars": 1074,
"preview": "MIT License\n\nCopyright (c) 2017 Prateek Bhatnagar\n\nPermission is hereby granted, free of charge, to any person obtaining"
},
{
"path": "README.md",
"chars": 2478,
"preview": "# preact-async-route\n[](https://api.tr"
},
{
"path": "example/app.js",
"chars": 783,
"preview": "import { h, render } from 'preact';\nimport {Router, Route, route} from 'preact-router';\nimport AsyncRoute from '../src/'"
},
{
"path": "example/components/Home.js",
"chars": 228,
"preview": "import {h, Component} from 'preact';\nimport {Link} from 'preact-router';\n\nexport default class Home extends Component {\n"
},
{
"path": "example/components/Profile.js",
"chars": 432,
"preview": "import {h, Component} from 'preact';\nimport {Link, route} from 'preact-router';\n\nexport default class Home extends Compo"
},
{
"path": "example/components/Terms.js",
"chars": 154,
"preview": "import {h, Component} from 'preact';\n\nexport default class Terms extends Component {\n\trender() {\n\t\treturn <h1>This is te"
},
{
"path": "example/index.html",
"chars": 123,
"preview": "<html><head></head><body><div id=\"app\"></div><script type=\"text/javascript\" src=\"/public/js/app.js\"></script></body></ht"
},
{
"path": "example/npm-debug.log",
"chars": 2819,
"preview": "0 info it worked if it ends with ok\n1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'run', 'test' ]\n2 info "
},
{
"path": "example/package.json",
"chars": 395,
"preview": "{\n \"name\": \"example\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo"
},
{
"path": "example/webpack.config.js",
"chars": 648,
"preview": "const HtmlWebpackPlugin = require('html-webpack-plugin');\nconst config = {\n\tentry: {\n\t\tapp: './app'\n\t},\n\toutput: {\n\t\tpat"
},
{
"path": "karma.conf.js",
"chars": 502,
"preview": "module.exports = function(config) {\n\tconfig.set({\n\t\tframeworks: ['mocha', 'chai-sinon'],\n\t\treporters: ['mocha'],\n\t\tbrows"
},
{
"path": "package.json",
"chars": 2455,
"preview": "{\n \"name\": \"preact-async-route\",\n \"version\": \"2.2.1\",\n \"description\": \"Async route component for preact-router\",\n \"m"
},
{
"path": "rollup.config.js",
"chars": 629,
"preview": "import fs from 'fs';\nimport babel from 'rollup-plugin-babel';\nimport minify from 'rollup-plugin-minify';\nconst packageDe"
},
{
"path": "src/index.d.ts",
"chars": 463,
"preview": "import { Component, FunctionalComponent } from 'preact';\n\ninterface IAsyncRouteProps {\n path: string;\n component?:"
},
{
"path": "src/index.js",
"chars": 1556,
"preview": "import { h, Component } from 'preact';\n\nclass AsyncRoute extends Component {\n\tconstructor() {\n\t\tsuper();\n\t\tthis.state = "
},
{
"path": "tests/index.js",
"chars": 4837,
"preview": "import { h, render, Component, options } from 'preact';\nimport Router,{route} from 'preact-router';\nimport AsyncRoute fr"
},
{
"path": "tests/ts/index.tsx",
"chars": 968,
"preview": "import { h, render, Component } from 'preact';\nimport Router from 'preact-router';\nimport AsyncRoute from '../../';\n\n/**"
},
{
"path": "tests/ts/tsconfig.json",
"chars": 372,
"preview": "{\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\"noImplici"
}
]
About this extraction
This page contains the full source code of the prateekbh/preact-async-route GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 22 files (22.2 KB), approximately 6.9k tokens, and a symbol index with 29 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.