Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add subscribe function and observable compatibility #269

Merged
merged 2 commits into from
Apr 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion packages/router5/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ declare module 'router5' {
CancelFn,
Options as NavigationOptions
} from 'router5/core/navigation'
import { SubscribeFn, SubscribeState } from 'router5/core/observable'
import { Middleware, MiddlewareFactory } from 'router5/core/middleware'
import { Plugin, PluginFactory } from 'router5/core/plugins'
import {
Expand Down Expand Up @@ -52,7 +53,9 @@ declare module 'router5' {
Router,
RouterOptions,
State,
StateMeta
StateMeta,
SubscribeFn,
SubscribeState
}

export default createRouter
Expand Down Expand Up @@ -246,6 +249,22 @@ declare module 'router5/core/navigation' {
}
}

declare module 'router5/core/observable' {
import { State } from 'router5'

export interface SubscribeState {
route: State
previousRoute: State
}
export type SubscribeFn = (state: SubscribeState) => void

module 'router5/create-router' {
interface Router {
subscribe(cb: SubscribeFn): void
}
}
}

declare module 'router5/core/plugins' {
import { Dependencies, Router, State } from 'router5/create-router'
import { NavigationOptions } from 'router5/core/navigation'
Expand Down
63 changes: 63 additions & 0 deletions packages/router5/modules/core/observable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import $$observable from 'symbol-observable'

function observerPlugin(router) {
let listeners = []

function unsubscribe(listener) {
if (listener) {
listeners = listeners.filter(l => l !== listener)
}
}

function subscribe(listener) {
listeners.concat(listener)

return unsubscribe(listener)
}

function observable() {
return {
subscribe(observer) {
if (typeof observer !== 'object' || observer === null) {
throw new TypeError(
'Expected the observer to be an object.'
)
}

function listener() {
if (observer.next) {
observer.next(router.getState())
}
}

listener()
const unsubscribe = subscribe(listener)
return { unsubscribe }
},

[$$observable]() {
return this
}
}
}

router.subscribe = subscribe
router[$$observable] = observable

return {
onTransitionSuccess: (toState, fromState) => {
listeners.forEach(listener =>
listener({
route: toState,
previousRoute: fromState
})
)
}
}
}

observerPlugin.pluginName = 'OBSERVABLE_PLUGIN'

export default function withObservablePlugin(router) {
router.usePlugin(observerPlugin)
}
2 changes: 2 additions & 0 deletions packages/router5/modules/create-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import withUtils from './core/utils'
import withRouterLifecycle from './core/router-lifecycle'
import withNavigation from './core/navigation'
import withMiddleware from './core/middleware'
import withObservable from './core/observable'
import withPlugins from './core/plugins'
import withRouteLifecycle from './core/route-lifecycle'
import withCloning from './core/clone'
Expand Down Expand Up @@ -98,6 +99,7 @@ function createRouter(routes, opts = {}, deps = {}) {
withUtils(router)
withPlugins(router)
withMiddleware(router)
withObservable(router)
withRouteLifecycle(router)
withRouterLifecycle(router)
withNavigation(router)
Expand Down
3 changes: 2 additions & 1 deletion packages/router5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"homepage": "http://router5.github.io",
"dependencies": {
"route-node": "3.1.0",
"router5-transition-path": "^5.1.1"
"router5-transition-path": "^5.1.1",
"symbol-observable": "1.2.0"
},
"typings": "./index.d.ts"
}
8 changes: 8 additions & 0 deletions packages/router5/test/typescript/core/observable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/// <reference path="../../../index.d.ts" />

import createRouter, { SubscribeFn } from 'router5'

let router = createRouter([])

const subscribeFn: SubscribeFn = ({ route, previousRoute }) => {}
router.subscribe(subscribeFn)
8 changes: 8 additions & 0 deletions packages/router5/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ route-node@3.1.0:
path-parser "4.0.4"
search-params "2.1.2"

router5-transition-path@^5.1.1:
version "5.2.0"
resolved "https://registry.yarnpkg.com/router5-transition-path/-/router5-transition-path-5.2.0.tgz#25ae7f75a12a17044f7766a180eb7377f372493c"

search-params@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/search-params/-/search-params-2.1.2.tgz#e0107b7e6f2e973d7991b8fbffc8b6664bc96edd"

symbol-observable@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"