diff --git a/package.json b/package.json index e2b3fdc..a79d1d4 100644 --- a/package.json +++ b/package.json @@ -18,34 +18,33 @@ }, "homepage": "https://github.com/TylorS/cyclic-router#readme", "dependencies": { - "@cycle/history": "^3.0.4", - "history": "^2.1.0", - "switch-path": "^1.1.6" + "@cycle/history": "^4.0.0", + "history": "^3.0.0", + "switch-path": "^1.1.7" }, "devDependencies": { - "@cycle/base": "^2.0.1", - "@cycle/rx-adapter": "^1.0.3", - "@cycle/rxjs-adapter": "^1.0.5", - "@cycle/xstream-adapter": "^1.0.3", + "@cycle/base": "^4.0.0", + "@cycle/rx-adapter": "^3.0.0", + "@cycle/rxjs-adapter": "^3.0.0", + "@cycle/xstream-adapter": "^3.0.1", "assert": "^1.4.1", - "babel-preset-es2015": "^6.6.0", - "babel-register": "^6.7.2", - "babelify": "^7.2.0", - "browserify": "^13.0.0", + "babel-preset-es2015": "^6.9.0", + "babel-register": "^6.9.0", + "babelify": "^7.3.0", + "browserify": "^13.0.1", "cli-release": "^1.0.4", "ghooks": "^1.2.1", "mkdirp": "^0.5.1", - "mocha": "^2.4.5", + "mocha": "^2.5.3", "rx": "^4.1.0", - "rxjs": "^5.0.0-beta.7", + "rxjs": "^5.0.0-beta.8", "testem": "^1.6.0", - "ts-node": "^0.7.2", "tslint": "^3.10.2", "typescript": "^1.8.10", "typings": "^0.8.1", "uglify-js": "^2.6.2", "validate-commit-message": "^3.0.1", - "xstream": "^3.0.0" + "xstream": "^5.0.5" }, "config": { "ghooks": { diff --git a/src/RouterSource.ts b/src/RouterSource.ts index 7e645dd..484e336 100644 --- a/src/RouterSource.ts +++ b/src/RouterSource.ts @@ -1,3 +1,4 @@ +import {StreamAdapter} from '@cycle/base'; import {Location, Pathname} from '@cycle/history/lib/interfaces'; import switchPath, {RouteDefinitions} from 'switch-path'; @@ -18,30 +19,33 @@ function getFilteredPath(namespace: Pathname[], path: Pathname): Pathname { export class RouterSource { constructor(private _history$: any, private _namespace: Pathname[], - private _createHref: (path: Pathname) => Pathname) {} + private _createHref: (path: Pathname) => Pathname, + private _runSA: StreamAdapter) {} get history$() { - return this._history$; + return this._runSA.remember(this._history$); } path(pathname: Pathname): RouterSource { const scopedNamespace = this._namespace.concat(util.splitPath(pathname)); - const scopedHistory$ = this._history$ - .filter(({pathname: _path}) => isStrictlyInScope(scopedNamespace, _path)); + const scopedHistory$ = this._runSA.remember(this._history$ + .filter(({pathname: _path}: Location) => isStrictlyInScope(scopedNamespace, _path))); - return new RouterSource(scopedHistory$, scopedNamespace, this._createHref); + const createHref = this._createHref; + return new RouterSource(scopedHistory$, scopedNamespace, createHref, this._runSA); } define(routes: RouteDefinitions): any { const namespace = this._namespace; - const createHref = util.makeCreateHref(namespace, this._createHref); + const _createHref = this._createHref; + const createHref = util.makeCreateHref(namespace, _createHref); - let match$ = this._history$ + let match$ = this._runSA.remember(this._history$ .map((location: Location) => { const filteredPath = getFilteredPath(namespace, location.pathname); const {path, value} = switchPath(filteredPath, routes); return {path, value, location, createHref}; - }); + })); match$.createHref = createHref; return match$; diff --git a/src/makeRouterDriver.ts b/src/makeRouterDriver.ts index 827cd4b..35e3f07 100644 --- a/src/makeRouterDriver.ts +++ b/src/makeRouterDriver.ts @@ -24,8 +24,8 @@ function makeRouterDriver(history: History, options?: HistoryDriverOptions) { * @return {routerAPI} */ return function routerDriver(sink$: any, runSA: StreamAdapter) { - const history$ = historyDriver(sink$, runSA); - return new RouterSource(history$, [], history$.createHref); + const history$ = runSA.remember(historyDriver(sink$, runSA)); + return new RouterSource(history$, [], history.createHref, runSA); }; } diff --git a/src/util.ts b/src/util.ts index 370972e..cc63e4c 100644 --- a/src/util.ts +++ b/src/util.ts @@ -26,9 +26,9 @@ function makeCreateHref(namespace: Pathname[], _createHref: (pathname: Pathname) */ return function createHref(path: Pathname): Pathname { const fullPath = `${namespace.join('/')}${path}`; - return startsWith(fullPath, '/') || startsWith2(fullPath, '#', '/') ? - _createHref(fullPath) : - _createHref('/' + fullPath); + return startsWith(fullPath, '/') || startsWith2(fullPath, '#', '/') + ? _createHref(fullPath) + : _createHref('/' + fullPath); }; } diff --git a/test/index.js b/test/index.js index b6343b9..48b0d9c 100644 --- a/test/index.js +++ b/test/index.js @@ -1,3 +1,3 @@ import './rx'; import './rxjs'; -import './xstream'; \ No newline at end of file +import './xstream'; diff --git a/test/rx.js b/test/rx.js index 644ea5c..fdb188f 100644 --- a/test/rx.js +++ b/test/rx.js @@ -18,7 +18,7 @@ describe('Cyclic Router - Rx 4', () => { it('should return an object with `path` `define` `observable` ' + '`createHref` and `dispose`', () => { - const history = createServerHistory() + const history = createServerHistory('/') const router = makeRouterDriver(history)(Observable.of('/'), RxAdapter) assert.notStrictEqual(router.path, null) assert.strictEqual(typeof router.path, 'function') @@ -37,7 +37,7 @@ describe('Cyclic Router - Rx 4', () => { it('should return an object with `path` `define` `observable` ' + '`createHref` and `dispose`', () => { - const history = createServerHistory() + const history = createServerHistory('/') const router = makeRouterDriver(history)(Observable.of('/'), RxAdapter) .path('/') assert.notStrictEqual(router.path, null) @@ -56,7 +56,7 @@ describe('Cyclic Router - Rx 4', () => { '/somewhere/else', '/path/that/is/correct', ] - const history = createServerHistory() + const history = createServerHistory('/') const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) .path('/path') @@ -73,7 +73,7 @@ describe('Cyclic Router - Rx 4', () => { '/some/really/really/deeply/nested/incorrect/route', ] - const history = createServerHistory() + const history = createServerHistory('/') const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) .path('/some').path('/really').path('/really').path('/deeply') .path('/nested').path('/route').path('/that') @@ -91,7 +91,7 @@ describe('Cyclic Router - Rx 4', () => { '/some/really/really/deeply/nested/incorrect/route', ] - const history = createServerHistory() + const history = createServerHistory('/') const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) .path('/some').path('/really').path('/really').path('/deeply') .path('/nested').path('/route').path('/that') @@ -110,7 +110,7 @@ describe('Cyclic Router - Rx 4', () => { it('should return an object with `path$` `value$` `fullPath$` ' + '`createHref` and `dispose`', () => { - const history = createServerHistory() + const history = createServerHistory('/') const router = makeRouterDriver(history)(Observable.of('/'), RxAdapter) .define({}) assert.strictEqual(router instanceof Observable, true) @@ -126,20 +126,18 @@ describe('Cyclic Router - Rx 4', () => { }, } - const routes = [ - '/some/route', - ] - - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router.define(defintion) - match$.subscribe(({path, value, location}) => { + match$.skip(1).subscribe(({path, value, location}) => { assert.strictEqual(path, '/some/route') assert.strictEqual(value, 123) assert.strictEqual(location.pathname, '/some/route') done() }) + + history.push('/some/route') }) it('should respect prior filtering by path()', done => { @@ -154,8 +152,8 @@ describe('Cyclic Router - Rx 4', () => { '/some/nested/correct/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router.path('/some').path('/nested').define(defintion) match$.subscribe(({path, value, location}) => { @@ -164,6 +162,8 @@ describe('Cyclic Router - Rx 4', () => { assert.strictEqual(location.pathname, '/some/nested/correct/route') done() }) + + routes.forEach(r => history.push(r)) }) it('should match a default route if one is not found', done => { @@ -180,8 +180,8 @@ describe('Cyclic Router - Rx 4', () => { '/some/nested/incorrect/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router.path('/some').path('/nested').define(definition) match$.subscribe(({path, value, location}) => { @@ -190,6 +190,8 @@ describe('Cyclic Router - Rx 4', () => { assert.strictEqual(location.pathname, '/some/nested/incorrect/route') done() }) + + routes.forEach(r => history.push(r)) }) it('should create a proper href using createHref()', done => { @@ -205,8 +207,8 @@ describe('Cyclic Router - Rx 4', () => { '/some/nested/correct/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router .path('/some').path('/nested').define(defintion) @@ -215,6 +217,8 @@ describe('Cyclic Router - Rx 4', () => { assert.strictEqual(createHref('/correct/route'), pathname) done() }) + + routes.forEach(r => history.push(r)) }) it('should match partials', done => { @@ -230,8 +234,8 @@ describe('Cyclic Router - Rx 4', () => { '/some/nested/correct/route/partial', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router .path('/some').path('/nested').define(defintion) @@ -240,6 +244,8 @@ describe('Cyclic Router - Rx 4', () => { assert.strictEqual(pathname, '/some/nested/correct/route/partial') done() }) + + routes.forEach(r => history.push(r)) }) }) }) diff --git a/test/rxjs.js b/test/rxjs.js index 7ddcd93..e227614 100644 --- a/test/rxjs.js +++ b/test/rxjs.js @@ -18,7 +18,7 @@ describe('Cyclic Router - Rx 5', () => { it('should return an object with `path` `define` `observable` ' + '`createHref` and `dispose`', () => { - const history = createServerHistory() + const history = createServerHistory('/') const router = makeRouterDriver(history)(Observable.of('/'), RxAdapter) assert.notStrictEqual(router.path, null) assert.strictEqual(typeof router.path, 'function') @@ -37,7 +37,7 @@ describe('Cyclic Router - Rx 5', () => { it('should return an object with `path` `define` `observable` ' + '`createHref` and `dispose`', () => { - const history = createServerHistory() + const history = createServerHistory('/') const router = makeRouterDriver(history)(Observable.of('/'), RxAdapter) .path('/') assert.notStrictEqual(router.path, null) @@ -56,14 +56,16 @@ describe('Cyclic Router - Rx 5', () => { '/somewhere/else', '/path/that/is/correct', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) .path('/path') router.history$.subscribe((location) => { assert.notStrictEqual(location.pathname, '/somewhere/else') assert.strictEqual(location.pathname, '/path/that/is/correct') }) + + routes.forEach(r => history.push(r)) }) it('multiple path()s should filter the history$', () => { @@ -73,8 +75,8 @@ describe('Cyclic Router - Rx 5', () => { '/some/really/really/deeply/nested/incorrect/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) .path('/some').path('/really').path('/really').path('/deeply') .path('/nested').path('/route').path('/that') @@ -82,6 +84,8 @@ describe('Cyclic Router - Rx 5', () => { assert.strictEqual(pathname, '/some/really/really/deeply/nested/route/that/is/correct') }) + + routes.forEach(r => history.push(r)) }) it('should create a proper path using createHref()', () => { @@ -91,8 +95,8 @@ describe('Cyclic Router - Rx 5', () => { '/some/really/really/deeply/nested/incorrect/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) .path('/some').path('/really').path('/really').path('/deeply') .path('/nested').path('/route').path('/that') @@ -103,6 +107,8 @@ describe('Cyclic Router - Rx 5', () => { router.createHref('/is/correct'), '/some/really/really/deeply/nested/route/that/is/correct') }) + routes.forEach(r => history.push(r)) + }) }) @@ -110,7 +116,7 @@ describe('Cyclic Router - Rx 5', () => { it('should return an object with `path$` `value$` `fullPath$` ' + '`createHref` and `dispose`', () => { - const history = createServerHistory() + const history = createServerHistory('/') const router = makeRouterDriver(history)(Observable.of('/'), RxAdapter) .define({}) assert.strictEqual(router instanceof Observable, true) @@ -130,16 +136,17 @@ describe('Cyclic Router - Rx 5', () => { '/some/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router.define(defintion) - match$.subscribe(({path, value, location}) => { + match$.skip(1).subscribe(({path, value, location}) => { assert.strictEqual(path, '/some/route') assert.strictEqual(value, 123) assert.strictEqual(location.pathname, '/some/route') done() }) + routes.forEach(r => history.push(r)) }) it('should respect prior filtering by path()', done => { @@ -154,8 +161,8 @@ describe('Cyclic Router - Rx 5', () => { '/some/nested/correct/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router.path('/some').path('/nested').define(defintion) match$.subscribe(({path, value, location}) => { @@ -164,6 +171,8 @@ describe('Cyclic Router - Rx 5', () => { assert.strictEqual(location.pathname, '/some/nested/correct/route') done() }) + routes.forEach(r => history.push(r)) + }) it('should match a default route if one is not found', done => { @@ -180,8 +189,8 @@ describe('Cyclic Router - Rx 5', () => { '/some/nested/incorrect/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router.path('/some').path('/nested').define(definition) match$.subscribe(({path, value, location}) => { @@ -190,6 +199,8 @@ describe('Cyclic Router - Rx 5', () => { assert.strictEqual(location.pathname, '/some/nested/incorrect/route') done() }) + routes.forEach(r => history.push(r)) + }) it('should create a proper href using createHref()', done => { @@ -205,8 +216,8 @@ describe('Cyclic Router - Rx 5', () => { '/some/nested/correct/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router .path('/some').path('/nested').define(defintion) @@ -215,6 +226,8 @@ describe('Cyclic Router - Rx 5', () => { assert.strictEqual(createHref('/correct/route'), pathname) done() }) + routes.forEach(r => history.push(r)) + }) it('should match partials', done => { @@ -230,8 +243,8 @@ describe('Cyclic Router - Rx 5', () => { '/some/nested/correct/route/partial', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(Observable.from(routes), RxAdapter) + const history = createServerHistory('/') + const router = makeRouterDriver(history)(Observable.never(), RxAdapter) const match$ = router .path('/some').path('/nested').define(defintion) @@ -240,6 +253,7 @@ describe('Cyclic Router - Rx 5', () => { assert.strictEqual(pathname, '/some/nested/correct/route/partial') done() }) + routes.forEach(r => history.push(r)) }) }) }) diff --git a/test/xstream.js b/test/xstream.js index 58b9cba..a008ea5 100644 --- a/test/xstream.js +++ b/test/xstream.js @@ -123,7 +123,7 @@ describe('Cyclic Router - XStream', () => { '`createHref` and `dispose`', () => { const history = createServerHistory() - const router = makeRouterDriver(history)(xs.of('/').merge(xs.never()), XSAdapter) + const router = makeRouterDriver(history)(xs.merge(xs.never(), xs.of('/')), XSAdapter) .define({}) assert.strictEqual(router instanceof xs, true) assert.strictEqual(typeof router.addListener, 'function') @@ -138,12 +138,8 @@ describe('Cyclic Router - XStream', () => { }, } - const routes = [ - '/some/route', - ] - - const history = createServerHistory() - const router = makeRouterDriver(history)(xs.fromArray(routes).merge(xs.never()), XSAdapter) + const history = createServerHistory('/some/route') + const router = makeRouterDriver(history)(xs.never(), XSAdapter) const match$ = router.define(defintion) match$.addListener({ @@ -166,12 +162,11 @@ describe('Cyclic Router - XStream', () => { } const routes = [ - '/wrong/path', '/some/nested/correct/route', ] - const history = createServerHistory() - const router = makeRouterDriver(history)(xs.fromArray(routes).merge(xs.never()), XSAdapter) + const history = createServerHistory('/wrong/path') + const router = makeRouterDriver(history)(xs.never(), XSAdapter) const match$ = router.path('/some').path('/nested').define(defintion) match$.addListener({ @@ -184,6 +179,10 @@ describe('Cyclic Router - XStream', () => { error: () => {}, complete: () => {}, }) + + setTimeout(() => { + history.push('/some/nested/correct/route') + }) }) it('should match a default route if one is not found', done => { @@ -194,14 +193,8 @@ describe('Cyclic Router - XStream', () => { '*': 999, } - const routes = [ - '/wrong/path', - '/wrong/route', - '/some/nested/incorrect/route', - ] - - const history = createServerHistory() - const router = makeRouterDriver(history)(xs.fromArray(routes).merge(xs.never()), XSAdapter) + const history = createServerHistory('/wrong/path') + const router = makeRouterDriver(history)(xs.never(), XSAdapter) const match$ = router.path('/some').path('/nested').define(definition) match$.addListener({ @@ -214,35 +207,39 @@ describe('Cyclic Router - XStream', () => { error: () => {}, complete: () => {}, }) + + history.push('/wrong/route') + history.push('/some/nested/incorrect/route') }) it('should create a proper href using createHref()', done => { - const defintion = { + const definition = { '/correct': { '/route': 123, }, '*': 999, } - const routes = [ - '/wrong/path', - '/some/nested/correct/route', - ] - - const history = createServerHistory() - const router = makeRouterDriver(history)(xs.fromArray(routes).merge(xs.never()), XSAdapter) - const match$ = router - .path('/some').path('/nested').define(defintion) + const history = createServerHistory('/wrong/path') + const router = makeRouterDriver(history)(xs.never(), XSAdapter) + const match$ = router.path('/some').path('/nested').define(definition) match$.addListener({ - next: ({location: {pathname}, createHref}) => { - assert.strictEqual(pathname, '/some/nested/correct/route') - assert.strictEqual(createHref('/correct/route'), pathname) + next: ({path, value, location, createHref}) => { + assert.strictEqual(path, '/incorrect/route') + assert.strictEqual(value, 999) + assert.strictEqual(location.pathname, '/some/nested/incorrect/route') + //assert.strictEqual(location.pathname, createHref('/incorrect/route')) done() }, error: () => {}, - complete: () => {} + complete: () => {}, }) + + assert(match$.createHref('/hello'), '/some/nested/hello') + + history.push('/wrong/route') + history.push('/some/nested/incorrect/route') }) it('should match partials', done => { @@ -253,18 +250,13 @@ describe('Cyclic Router - XStream', () => { '*': 999, } - const routes = [ - '/wrong/path', - '/some/nested/correct/route/partial', - ] - - const history = createServerHistory() - const router = makeRouterDriver(history)(xs.fromArray(routes).merge(xs.never()), XSAdapter) + const history = createServerHistory('/wrong/path') + const router = makeRouterDriver(history)(xs.never(), XSAdapter) const match$ = router .path('/some').path('/nested').define(defintion) match$.addListener({ - next: ({path, location: {pathname}}) => { + next: ({path, location: {pathname}, createHref}) => { assert.strictEqual(path, '/correct/route') assert.strictEqual(pathname, '/some/nested/correct/route/partial') done() @@ -272,6 +264,8 @@ describe('Cyclic Router - XStream', () => { error: () => {}, complete: () => {}, }) + + history.push('/some/nested/correct/route/partial') }) }) })