Skip to content

Instantly share code, notes, and snippets.

@TylorS
Created October 5, 2015 01:16
Show Gist options
  • Save TylorS/2a821e0e350b1ddd596b to your computer and use it in GitHub Desktop.
Save TylorS/2a821e0e350b1ddd596b to your computer and use it in GitHub Desktop.
const {run} = require(`@cycle/core`)
const {makeDOMDriver} = require(`@cycle/dom`)
const {makeHistoryDriver} = require(`cycle-history`)
const {Main} = require(`./app/dialogue/Main`)
function clientSideApp(responses) {
let requests = Main(responses)
requests.History = requests.History.skip(1)
requests.DOM = requests.DOM.skip(1)
return requests
}
run(clientSideApp, {
DOM: makeDOMDriver(`.app`),
History: makeHistoryDriver({
hash: false,
query: true,
}),
})
let Cycle = require(`@cycle/core`)
let express = require(`express`)
let browserify = require(`browserify`)
let {Rx} = Cycle
let {h, makeHTMLDriver} = require(`@cycle/dom`)
let {makeServerHistoryDriver} = require(`cycle-history`)
let {Main} = require(`./app/dialogue/Main`) // wherever your main function is
// make sure that your refactor if your name is not 'Main'
function wrapVTreeWithHTMLBoilerplate(vtree, clientBundle) {
return h(`html`, [
h(`head`, [
h(`title`, `Cycle Isomorphism Example`),
]),
h(`body`, [
h(`div`, {className: `app`}, [vtree]),
h(`script`, clientBundle),
]),
])
}
function prependHTML5Doctype(html) {
return `<!doctype html>${html}`
}
function wrapAppResultWithBoilerplate(appFn, bundle$) {
return function wrappedAppFn(ext) {
let requests = appFn(ext)
let vtree$ = requests.DOM.take(1)
let wrappedVTree$ = Rx.Observable.combineLatest(vtree$, bundle$,
wrapVTreeWithHTMLBoilerplate
)
return {
DOM: wrappedVTree$,
History: requests.History.take(1),
}
}
}
let clientBundle$ = (() => {
let replaySubject = new Rx.ReplaySubject(1)
let bundleString = ``
let bundleStream = browserify()
.transform(`babelify`)
.transform({global: true}, `uglifyify`)
.add(`./src/clientBundle.js`)
.bundle()
bundleStream.on(`data`, function addData(data) {
bundleString += data
})
bundleStream.on(`end`, function streamComplete() {
replaySubject.onNext(bundleString)
replaySubject.onCompleted()
console.log(`Client bundle successfully compiled.`)
})
return replaySubject
})()
let server = express()
server.use(function cycleServer(req, res) {
// Ignore favicon requests
if (req.url === `/favicon.ico`) {
res.writeHead(200, {'Content-Type': `image/x-icon`})
res.end()
return
}
console.log(`req: ${req.method} ${req.url}`)
let wrappedAppFn = wrapAppResultWithBoilerplate(Main, clientBundle$)
/*eslint-disable */
let [requests, responses] = Cycle.run(wrappedAppFn, {
/*eslint-enable */
DOM: makeHTMLDriver(),
History: makeServerHistoryDriver({
pathname: req.url,
}),
})
let html$ = responses.DOM.map(prependHTML5Doctype)
html$.subscribe(html => res.send(html))
})
let port = process.env.PORT || 3000
server.listen(port)
console.log(`Listening on port ${port}`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment