Skip to content

Commit 1671ce2

Browse files
committed
set up groundwork for interactive mode
1 parent c827112 commit 1671ce2

10 files changed

+9121
-975
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
/node_modules
33
npm-debug.log
44
lib/
5+
.cache
6+
dist/

.npmignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ test
66
Makefile
77
wercker.yml
88
stuff
9+
.cache

.prettierrc

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"printWidth": 80,
3+
"proseWrap": "always",
4+
"semi": false,
5+
"singleQuote": true,
6+
"bracketSpacing": true,
7+
"arrowParens": "always"
8+
}

package-lock.json

+8,975-970
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+16-1
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@
1111
"scripts": {
1212
"test": "make test",
1313
"test-ci": "make test && make test-func",
14-
"test-local": "make test && make docker-test-func"
14+
"test-local": "make test && make docker-test-func",
15+
"build-web:watch": "parcel serve --no-source-maps web/index.html",
16+
"build:watch": "watchy -w 'src/**' -- make"
1517
},
1618
"bin": {
1719
"ramda": "./bin/ramda"
1820
},
21+
"browser": {
22+
"./lib/config": false
23+
},
1924
"author": "Raine Virta <[email protected]>",
2025
"license": "ISC",
2126
"dependencies": {
@@ -24,23 +29,33 @@
2429
"camelize": "^1.0.0",
2530
"debug": "^4.1.0",
2631
"editor": "^1.0.0",
32+
"express": "^4.16.4",
2733
"fast-csv": "^2.4.1",
2834
"flat": "^4.1.0",
2935
"is-there": "^4.4.3",
3036
"livescript": "^1.6.0",
3137
"minimist": "^1.2.0",
38+
"opn": "^5.4.0",
39+
"polka": "^0.5.1",
3240
"ramda": "0.26.1",
41+
"serve-static": "^1.13.2",
3342
"split2": "^3.0.0",
43+
"string-argv": "^0.1.1",
3444
"through2": "^3.0.0",
3545
"transduce-stream": "^0.5.0"
3646
},
3747
"devDependencies": {
3848
"chai": "^4.2.0",
3949
"concat-stream": "^1.6.2",
50+
"lodash.debounce": "^4.0.8",
4051
"mocha": "^5.2.0",
52+
"parcel-bundler": "^1.10.3",
53+
"react": "^16.6.3",
54+
"react-dom": "^16.6.3",
4155
"rewire": "^4.0.1",
4256
"shelljs": "^0.8.3",
4357
"sinon": "^7.2.2",
58+
"string-to-stream": "^1.1.1",
4459
"strip-ansi": "^5.0.0"
4560
}
4661
}

src/argv.ls

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ HELP =
1010
"""
1111
Usage: ramda [options] [function] ...
1212
13+
--interactive interactive mode
1314
-f, --file read a function from a js/ls file instead of args; useful for
1415
larger scripts
1516
-c, --compact compact output for JSON and tables
@@ -66,7 +67,7 @@ export parse = (argv) ->
6667
argv = map (wrap-number-lookup << wrap-function), argv.slice 2
6768
args = camelize minimist argv,
6869
string: <[ file input-type output-type json-path csv-delimiter ]>
69-
boolean: <[ compact slurp unslurp pretty verbose version raw-input raw-output configure no-stdin js transduce headers ]>
70+
boolean: <[ compact slurp unslurp pretty verbose version raw-input raw-output configure no-stdin js transduce headers interactive ]>
7071
alias: parse-aliases HELP
7172
default: {+stdin, +headers, 'csv-delimiter': \,}
7273

src/main.ls

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env lsc
22
require! {vm, JSONStream, path: Path, split2, fs, camelize}
3-
require! <[ ./argv ./config ]>
3+
require! <[ ./argv ./config ./server ]>
44
require! './compile-fun'
55
require! through2: through
66
require! stream: {PassThrough}
@@ -128,7 +128,18 @@ make-input-stream = (die, opts, stdin) ->
128128
if opts.stdin then make-stdin-parser die, opts, stdin
129129
else blank-obj-stream!
130130

131-
main = (process-argv, stdin, stdout, stderr) ->
131+
append-buffer =
132+
(buf1, buf2) -> Buffer.concat([ buf1, buf2 ])
133+
134+
get-stream-as-promise = (stream, cb) ->
135+
new Promise (resolve, reject) ->
136+
res = null
137+
stream
138+
.pipe reduce-stream append-buffer, Buffer.alloc-unsafe 0
139+
.on 'data', (chunk) -> res := chunk
140+
.on 'end', -> resolve res
141+
142+
main = (process-argv, stdin, stdout, stderr) ->>
132143
stdout.on \error ->
133144
if it.code is 'EPIPE' then process.exit 0
134145

@@ -142,10 +153,17 @@ main = (process-argv, stdin, stdout, stderr) ->
142153

143154
if opts.help then return die argv.help!
144155
if opts.version then return die <| require '../package.json' .version
156+
145157
if opts.configure
146-
return config.edit (err) ->
158+
config.edit (err) ->
147159
if err != 0 or err then die err
148160
else process.exit 0
161+
return
162+
163+
if opts.interactive
164+
raw-stdin-buf = await get-stream-as-promise stdin
165+
server.start log-error, raw-stdin-buf, process-argv
166+
return
149167

150168
if opts.file
151169
try fun = require Path.resolve opts.file

src/server.ls

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
require! {path: Path}
2+
require! polka
3+
require! 'serve-static'
4+
require! opn
5+
6+
export start = (log-error, raw-stdin-buf, process-argv) ->
7+
app = polka!
8+
.use serve-static (Path.join __dirname, '..', 'dist'), {'index': ['index.html']}
9+
.get '/stdin', (req, res) ->
10+
res.write-head 200, 'Content-Type': 'text/plain'
11+
res.end raw-stdin-buf
12+
.get '/argv', (req, res) ->
13+
res.write-head 200, 'Content-Type': 'application/json'
14+
res.end JSON.stringify process-argv.slice 2
15+
.listen 63958, (err) ->
16+
log-error "listening at port #{app.server.address().port}"
17+
opn "http://localhost:#{app.server.address().port}", { wait: false }

web/index.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
5+
<meta charset="utf-8">
6+
</head>
7+
<body>
8+
<div id="root"></div>
9+
<script src="./index.js"></script>
10+
</body>
11+
</html>

web/index.js

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React from 'react'
2+
import { render } from 'react-dom'
3+
import stringToStream from 'string-to-stream'
4+
import JSONStream from 'JSONStream'
5+
import livescript from 'livescript'
6+
import debounce from 'lodash.debounce'
7+
import compileFun from '../lib/compile-fun'
8+
import { parse } from '../lib/argv'
9+
import stringArgv from 'string-argv'
10+
11+
const getStdin = () =>
12+
window
13+
.fetch('/stdin', {
14+
headers: { 'Content-Type': 'text/plain; charset=utf-8' }
15+
})
16+
.then((res) => res.text())
17+
18+
getStdin().then((str) => {
19+
doRender({ stdin: str })
20+
})
21+
22+
const die = (msg) => console.error(msg)
23+
24+
class App extends React.Component {
25+
constructor(props) {
26+
super(props)
27+
this.onInputChange = this.onInputChange.bind(this)
28+
this.evalInput = debounce(this.evalInput.bind(this), 300)
29+
this.state = {
30+
input: props.input
31+
}
32+
33+
this.evalInput()
34+
}
35+
36+
onInputChange(ev) {
37+
const val = ev.target.value
38+
this.setState({ input: val }, this.evalInput)
39+
}
40+
41+
evalInput() {
42+
const { stdin } = this.props
43+
const { input } = this.state
44+
const argv = stringArgv(input, 'node', 'dummy.js')
45+
const opts = parse(argv)
46+
const fun = compileFun(opts, die)
47+
}
48+
49+
render() {
50+
return (
51+
<div>
52+
<input
53+
type="text"
54+
value={this.state.input}
55+
onChange={(ev) => {
56+
ev.persist()
57+
this.onInputChange(ev)
58+
}}
59+
/>
60+
</div>
61+
)
62+
}
63+
}
64+
65+
const doRender = (props) =>
66+
render(<App {...props} />, document.getElementById('root'))
67+
68+
doRender({ stdin: null, input: 'identity' })

0 commit comments

Comments
 (0)