Skip to content

Instantly share code, notes, and snippets.

@okunishinishi
Last active February 7, 2017 06:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okunishinishi/2c8d34fc96ba254e359e69cac24dcd8b to your computer and use it in GitHub Desktop.
Save okunishinishi/2c8d34fc96ba254e359e69cac24dcd8b to your computer and use it in GitHub Desktop.
[SUGOS] チュートリアル03 - Browser間でやり取りする ref: http://qiita.com/okunishinishi@github/items/52206755d6fb0d3e844e
mkdir sugos-tutorial-03
cd sugos-tutorial-03
npm init -y
# Install dependencies
npm install -S sugo-actor sugo-caller sugo-hub co asleep react react-dom babel-polyfill
# Install dev dependencies
npm install -D browserify browserify-incremental xtend babelify babel-preset-es2015 babel-preset-react
#!/usr/bin/env node
'use strict'
const sugoHub = require('sugo-hub')
const co = require('co')
co(function * () {
let hub = sugoHub({
/** Directory name for static files */
static: [ 'public' ]
})
yield hub.listen(3000)
console.log(`SUGO Cloud started at port: ${hub.port}`)
}).catch((err) => {
console.error(err)
process.exit(1)
})
node ./hub.js
/**
* Sample JSX script for actor
*/
'use strict'
import 'babel-polyfill'
import sugoActor, {Module} from 'sugo-actor'
import React, {PropTypes as types} from 'react'
import ReactDOM from 'react-dom'
const ActorWorkspace = React.createClass({
propTypes: {
/** Key for actor */
actorKey: types.string
},
getInitialState () {
return {
html: `
<h3>This is <b>sample</b> dynamic html</h3>
<p>You can edit the contents from <a href="./caller.html">Caller page</a></p>
`
}
},
render () {
const s = this
let { state } = s
return (
<div className='actor-workspace'>
<div dangerouslySetInnerHTML={ { __html: state.html } }></div>
</div>
)
},
componentDidMount () {
const s = this
let { actorKey } = s.props
let actor = sugoActor({
key: actorKey,
modules: {
// Define a module to handle HTML
dynamicHTML: new Module({
// Read HTML string
read () {
return s.state.html
},
// Write HTML string
write (html) {
s.setState({ html })
}
})
}
})
actor.connect()
s.actor = actor
},
componentWillUnmount () {
const s = this
let { actor } = s
actor.disconnect()
}
})
window.addEventListener('DOMContentLoaded', () => {
ReactDOM.render(
<ActorWorkspace actorKey='my-actor-01'/>,
document.getElementById('actor-mount-root')
)
})
<!DOCTYPE html>
<html>
<head>
<title>[Tutorial-03] Actor Page</title>
<meta name="viewport" content="width=device-width">
<script src="./actor.js"></script>
<style>
body {
color: #555;
font-family: monospace;
padding: 50px;
}
h1 {
padding: 4px;
border-bottom: 2px solid #DEC010;
color: #5a4e07;
margin: 0 0 16px;
}
a {
color: #DEC010;
}
.container {
max-width: 1024px;
margin: 0 auto;
}
</style>
</head>
<body>
<header>
<div class="container">
<h1>[Tutorial-03] Actor Page</h1>
</div>
</header>
<main>
<div class="container">
<div id="actor-mount-root"><!-- Mount root for react --></div>
</div>
</main>
</body>
</html>
/**
* Sample JSX script for caller
*/
'use strict'
import 'babel-polyfill'
import sugoCaller, {Module} from 'sugo-caller'
import React, {PropTypes as types} from 'react'
import co from 'co'
import ReactDOM from 'react-dom'
const CallerWorkspace = React.createClass({
propTypes: {
/** Key for caller */
actorKey: types.string
},
getInitialState () {
return {
html: ''
}
},
render () {
const s = this
let { state } = s
return (
<div className='caller-workspace'>
<textarea name="html"
placeholder="HTML to Write"
value={ state.html }
onChange={ (e) => s.updateHTML(e.target.value) }
></textarea>
<fieldset>
<legend>Preview</legend>
<div dangerouslySetInnerHTML={ { __html: state.html } }></div>
</fieldset>
</div>
)
},
componentDidMount () {
const s = this
let { actorKey } = s.props
co(function * () {
let caller = sugoCaller({})
// Access to actor
let actor = yield caller.connect(actorKey).catch((err) => {
alert(`Failed to connect actor: ${actorKey}`)
})
// Get dynamic html module
let dynamicHTML = actor.get('dynamicHTML')
s.caller = caller
s.dynamicHTML = dynamicHTML
let html = yield dynamicHTML.read()
s.setState({ html })
s.forceUpdate()
}).catch((err) => console.error(err))
},
componentWillUnmount () {
const s = this
let { caller } = s
caller.disconnect()
},
updateHTML (html) {
const s = this
s.setState({ html })
// Apply HTML to remote
s.dynamicHTML.write(html)
console.log('html', html)
}
})
window.addEventListener('DOMContentLoaded', () => {
ReactDOM.render(
<CallerWorkspace actorKey='my-actor-01'/>,
document.getElementById('caller-mount-root')
)
})
<!DOCTYPE html>
<html>
<head>
<title>[Tutorial-03] Caller Page</title>
<meta name="viewport" content="width=device-width">
<script src="./caller.js"></script>
<style>
html {
background: #DEC010;
}
body {
color: #555;
font-family: monospace;
padding: 50px;
}
h1 {
padding: 4px;
border-bottom: 2px solid #DEC010;
color: #5a4e07;
margin: 0 0 16px;
}
a {
color: #DEC010;
}
.container {
max-width: 1024px;
margin: 0 auto;
}
textarea {
width: 100%;
min-height: 94px;
box-sizing: border-box;
outline-color: #DEC010;
}
fieldset {
background: white;
}
</style>
</head>
<body>
<header>
<div class="container">
<h1>[Tutorial-03] Caller Page</h1>
</div>
</header>
<main>
<div class="container">
<div id="caller-mount-root"><!-- Mount root for react --></div>
</div>
</main>
</body>
</html>
#!/usr/bin/env node
/**
* Build script
*/
'use strict'
const fs = require('fs')
const co = require('co')
const browserify = require('browserify')
const browserifyInc = require('browserify-incremental')
const xtend = require('xtend')
function bundle (src, dest) {
return new Promise((resolve, reject) => {
console.log(`Bundling ${src}...`)
let b = browserify(src, xtend(browserifyInc.args, {
// your custom opts
})).transform('babelify', {
babelrc: false,
presets: [ 'es2015', 'react' ]
})
browserifyInc(b, { cacheFile: './tmp/browserify-cache.json' })
b
.bundle()
.pipe(fs.createWriteStream(dest))
.on('error', (err) => {
console.error(err)
reject(err)
})
.on('close', () => {
console.log(`File bundled: ${dest}`)
resolve()
})
})
}
co(function * () {
yield bundle('public/actor.jsx', 'public/actor.js')
yield bundle('public/caller.jsx', 'public/caller.js')
})
node ./build.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment