OS.js Proc Provider
npm install @osjs/proc-provider

OS.js is an open-source web desktop platform with a window manager, application APIs, GUI toolkit, filesystem abstractions and much more.





Adds support for spawning and piping processes and pseudo terminals on the node server.
Communicates via the internal websocket.
``bash`
npm install @osjs/proc-provider
In your initialization scripts:
`javascript
// Client index.js file
import {ProcServiceProvider} from '@osjs/proc-provider';
osjs.register(ProcServiceProvider);
// Client index.scss file
@import "~@osjs/proc-provider/dist/main.css";
// Server index.js file
const {ProcServiceProvider} = require('@osjs/proc-provider/src/server.js');
osjs.register(ProcServiceProvider);
`
By default the server provider is set up to only allow users with the admin group to access this feature.
You can change this by adding options:
`javascript`
const {ProcServiceProvider} = require('@osjs/proc-provider/src/server.js');
osjs.register(ProcServiceProvider, {
args: {
groups: ['other-group']
}
});
You can reach this service with core.make('osjs/proc').
* pty(cmd, ...args) => Promise
- Creates a new pseudo terminal over websocketspawn(cmd, ...args) => Promise
*
- Spawns a new process over websocketexec(cmd, ...args) => Promise<{code, stdout, stderr}, Error>
* - Execs a process over httpxterm(win[, options]) => Xterm
* - Creates a new xterm.js class instance and bind it to a window
The cmd can either be a string, or an object: {cmd: string, env: {A: 'value'}}.
The p returned in a promise resolution is an EventEmitter with some special methods for interacting with the process.
See examples below.
Execute a process, but inside a PTY. This makes it possible to use interactive processes.
Note that it is not possible to differentiate between stdout and stderr in this case.
`javascript
core.make('osjs/proc')
.pty('ls')
.then(p => {
// Process events
p.on('data', str => console.log(str))
p.on('exit', code => console.info(code))
// Internal events
p.on('spawned', () => {}); // Spawn successful
p.on('error', error => console.error(error)); // Spawn errors
// Send data to the shell
p.send('Hello World\n');
// You can kill long running processes
p.kill();
})
`
Execute a process via standard node child_process.
Note that processes that requires an interactive shell won't work here. See PTY above.
`javascript
core.make('osjs/proc')
.spawn('ls')
.then(p => {
// Process events
p.on('stdout', str => console.log(str))
p.on('stderr', str => console.warn(str))
p.on('exit', code => console.info(code))
// Internal events
p.on('spawned', () => {}); // Spawn successful
p.on('error', error => console.error(error)); // Spawn errors
// You can kill long running processes
p.kill();
})
`
Directly execute a program via child_process and return the result.
`javascript`
core.make('osjs/proc')
.exec('ls')
.then(({stdout, stderr, code}) => console.log(stdout, stderr, code))
`javascript`
core.make('osjs/proc')
.spawn('ls', '-l') // Works for all methods
You can also pass environmental data to all methods.
`javascript`
core.make('osjs/proc')
.spawn({cmd: 'ls', env: {foo: 'bar'}}) // Works for all methods
For a PTY this also supports input. Just spawn a process as above, but:
`javascript
core.make('osjs/proc')
.pty('ls')
.then(p => {
const win = p.createWindow({
// Keep window open for as long as you want
keepOpen: false
})
// Close window after 2.5s when command is complete
p.on('exit', () => setTimeout(() => win.destroy(), 2500))
})
`
You can attach an Xterm (PTY recommended) to any arbitrary DOM element.
This example shows you how to use it in Hyperapp:
> Note that the xterm reference is a xterm.js class instance. The addon fit has been loaded and you can specify terminal options via the second argument: .xterm(win, {terminal: {}}).
`javascript
importĀ {h, app} from 'hyperapp';
import {Box} from '@osjs/gui';
// Create a custom hyperapp component
// The CSS is included by this provider
const XtermElement = props => h('div', {
class: 'osjs-gui osjs-gui-xterm',
oncreate: el => props.xterm.open(el),
onclick: () => props.xterm.focus()
});
// When you render your window, create a new Xterm reference
// Then provide it as a reference to the component
win.render(($content, win) => {
const pp = core.make('osjs/proc');
const xterm = pp.xterm(win);
const hyperapp = app({}, {
runPty: () => {
pp.pty('ls', '-l')
.then(p => p.attachXterm(xterm))
.catch(error => console.error(error));
}
}, (state, actions) => {
return h(Box, {
grow: 1,
shrink: 1
}, h(XtermElement, {xterm}));
}, $content);
// Execute immediately. You can call this action from a button or whatever
// using components
hyperapp.runPty();
});
`
- Launch processes via websocket (pipeable)
- Launch pseudo terminals via websocket (pipeable)
- Launch process via http
- Support for manually killing a running process
- Server clears out stale processes (ex when client disconnects)
- Works on all platforms
- [ ] Add option for spawning standalone socket
- [ ] Move the HTTP API purely to websocket signals ?
- [ ] Add a system socket and host service
- [ ] Add shell` method for direct PTY
* Sponsor on Github
* Become a Patreon
* Support on Open Collective
* Contribution Guide
See the Official Manuals for articles, tutorials and guides.
* Official Chat
* Community Forums and Announcements
* Homepage
* Twitter (author)
* Google+
* Facebook
* Docker Hub