1.0.3 • Published 5 years ago

websh v1.0.3

Weekly downloads
5
License
GPL-3.0-or-later
Repository
github
Last release
5 years ago
  • Web.sh

    This project aims to form kind of a shell for the web. It connects web-apps via window-messaging and let's you compose them like a shell-script. ** Tests

    #+BEGIN_SRC sh npm install npm test #+END_SRC ** API

    All public symbols are exported from the ~Websh.js~ module in the root of the repository. All other modules should be considered private and subject to change. *** ~websh(driver?: Driver = inlineIframeDriver()): Websh~

    This function is the default export of the module and the
    constructor for shell instances.  Each shell instance closes over
    a driver that abstracts the mechanism to talk to an iframe
    instance.  The default driver ~inlineIframeDriver~ creates a
    full-screen iframe automatically and uses it as output.  If you
    need more control over the creation and the style of the iframe
    use the ~iframeDriver~.  The function returns a `Websh` instance
    which is a function that expects the script as a string argument.
    
    #+BEGIN_SRC js
      import websh from './Websh.js'
    
      const sh = websh()
      sh('examples/input | examples/sed?regex=Foo&replace=bar | examples/cat')
        .then(output => {
          console.log(output)  // This is the received output
        })
    #+END_SRC

    *** ~iframeDriver(iframeElement: DOMElement): Driver~

    This is a more flexible driver than the default
    ~inlineIframeDriver~ which let's you control the iframe yourself.
    
    #+BEGIN_SRC js
      import websh, { iframeDriver } from './Websh.js'
    
      const driver = iframeDriver(document.getElementById('my-iframe'))
      const sh = websh(driver)
      // ...
    #+END_SRC

    ** Shell language

    The shell-language is designed to be lightweight and easy to pick-up and learn. It's heavily inspired by unix shell scripts. *** Example

    #+BEGIN_SRC sh
      # Pipelines
      https://mypage.com/prompt-input | https://secondpage.com/
    
      # Parameters
      https://mypage.com/prompt-input?text=Hello%20world
    #+END_SRC

    ** Program interface

    A script executes multiple so-called programs. These programs are web-apps that utilize the window messaging API to communicate with the system. *** Execution-flow

    - The program is being loaded in an ~iframe~
    - Then the content from the standard-input is being transmitted to
      the content-window of the iframe using the following command:
    
      #+BEGIN_SRC js
        iframe.contentWindow.postMessage(["stdin", [] /* Array of input lines */])
      #+END_SRC
    
      This ~Array of input lines~ is an array filled with data from
      the output that the previous program generated.  If this is the
      first program being executed the ~Array of input lines~ is an
      empty array.
    - The program should then use the input (or ignore if not need)
      and generate output using the ~print~ [[*System%20calls][system-call]]:
    
      #+BEGIN_SRC js
        window.parent.postMessage(["print", "Sample output" /* The output data */])
      #+END_SRC
    
      The ~print~ system-call can be used multiple times to generate
      multiple "output lines".
    - Once the program finishes it should use the ~exit~ system-call
      to handover the execution back to the system so that the next
      program can be called.

    *** System calls

    The system communication is handled by sys-call-like messages with
    the following syntax:
    
    #+BEGIN_SRC javascript
      ["print", { my: 'message' }]
    #+END_SRC
    
    - ~print(<chunks>, ...)~
    
      This command sends output chunks to the system.
    - ~exit(<exitCode>)~
    
      This command exits the currently running process and hands-over
      an exit code.  A non-zero exit-code means failure and stops the
      execution of the script immediately.

    ** Security implications

    • Commands that operate on sensible user-data should use the second parameter of ~window.parent.postMessage()~ to avoid sending data to malicious targets. ** Known issues

    • Pipe characters in the query params to a command aren't handled correctly ** Missing features

    • The shell web-app should itself act like a program. E.g. sent the input to the first program and send back the output to the calling system. ** Thoughts / ideas

    • Environment variables: Global variables that are passed to each program