Dune
Dune is an open-source, cross-platform, shell around the V8 engine, written in Rust and capable of running JavaScript (dah) and TypeScript code out of the box.
Developed completely for fun and experimentation.
Installation
Mac, Linux:
curl -fsSL https://raw.githubusercontent.com/aalykiot/dune/main/install.sh | sh
Windows (PowerShell)
irm https://raw.githubusercontent.com/aalykiot/dune/main/install.ps1 | iex
Otherwise you have to manually download and unzip the release build.
From Source:
Clone the repo and build it using Cargo.
git clone https://github.com/aalykiot/dune.git && cd ./dune && cargo build --release
Make sure to create a
.dune
directory under your user.
Getting Started
A simple example.
import shortid from 'https://cdn.skypack.dev/shortid';
console.log(shortid()); //=> "lXN1aGba2"
Another example using the net module.
import net from 'net';
const server = net.createServer(async (socket) => {
console.log('Got new connection!');
await socket.write('Hello! π\n');
await socket.destroy();
});
await server.listen(3000, '127.0.0.1');
console.log('Server is listening on port 3000...');
JSX/TSX files are also supported for server side rendering.
import { h, Component } from 'https://esm.sh/[email protected]';
import { render } from 'https://esm.sh/[email protected]';
/** @jsx h */
// Classical components work.
class Fox extends Component {
render({ name }) {
return <span class="fox">{name}</span>;
}
}
// ... and so do pure functional components:
const Box = ({ type, children }) => (
<div class={`box box-${type}`}>{children}</div>
);
let html = render(
<Box type="open">
<Fox name="Finn" />
</Box>
);
console.log(html);
For more examples look at the examples directory.
Available APIs
Globals
-
global
: Reference to the global object. -
globalThis
: Same asglobal
. -
console
: A subset of the WHATWG console. -
prompt
: Shows the given message and waits for the user's input. -
TextEncoder
/TextDecoder
: WHATWG encoding API. -
setTimeout
/setInterval
/clearTimeout
/clearInterval
: DOM style timers. -
setImmediate
/clearImmediate
: Node.js like immediate timers. -
process
: An object that provides info about the current dune process. -
structuredClone
: Creates a deep clone of a given value.
Module Metadata
-
import.meta.url
: A string representation of the fully qualified module URL. -
import.meta.main
: A flag that indicates if the current module is the main module. -
import.meta.resolve(specifier)
: A function that returns resolved specifier.
Process
-
argv
: An array containing the command-line arguments passed when the dune process was launched. -
cwd()
: Current working directory. -
env
: An object containing the user environment. -
exit(code?)
: Exits the program with the given code. -
getActiveResourcesInfo()
: An array of strings containing the types of the active resources that are currently keeping the event loop alive. -
memoryUsage()
: An object describing the memory usage. -
nextTick(cb, ...args?)
: Adds callback to the "next tick queue". -
pid
: PID of the process. -
platform
: A string identifying the operating system platform. -
uptime()
: A number describing the amount of time (in seconds) the process is running. -
version
: The dune version. -
versions
: An object listing the version strings of dune and its dependencies. -
binding(module)
: Exposes modules with bindings to Rust. -
kill(pid, signal?)
: Sends the signal to the process identified by pid. -
stdout
: Points to system'sstdout
stream. -
stdin
: Points to system'sstdin
stream. -
stderr
: Points to system'sstderr
stream.
File System
This module also includes a
Sync
method for every async operation available.
-
copyFile(src, dest)
: Copiessrc
todest
. -
createReadStream(path, options?)
: Returns a new readable IO stream. -
createWriteStream(path, options?)
: Returns a new writable IO stream. -
open(path, mode?)
: Asynchronous file open. -
mkdir(path, options?)
: Creates a directory. -
readFile(path, options?)
: Reads the entire contents of a file. -
rmdir(path, options?)
: Deletes a directory (must be empty). -
readdir(path)
: Reads the contents of a directory. -
rm(path, options?)
: Removes files and directories. -
rename(from, to)
: Renames the file from oldPath to newPath. -
stat(path)
: Retrieves statistics for the file. -
watch(path, options?)
: Returns an async iterator that watches for changes over a path. -
writeFile(path, data, options?)
: Writes data to the file, replacing the file if it already exists.
Data (to be written) must be of type String|Uint8Array.
File
-
fd
: The numeric file descriptor. -
close()
: Closes the file. -
read(size?, offset?)
: Reads data from the file. -
stat()
: Retrieves statistics for the file. -
write(data, offset?)
: Writes data to the file.
Net
-
createServer(connectionListener?)
: Creates a new TCP server. -
createConnection(options)
: Creates unix socket connection to a remote host. -
TimeoutError
: Custom error signalling a socket (read) timeout.
Net.Server
Net.Server is a class extending
EventEmitter
and implements@@asyncIterator
.
-
listen(port, host?)
: Begin accepting connections on the specified port and host. -
accept()
: Waits for a TCP client to connect and accepts the connection. -
address()
: Returns the bound address. -
close()
: Stops the server from accepting new connections and keeps existing connections. -
Event: 'listening'
: Emitted when the server has been bound after callingserver.listen
. -
Event: 'connection'
: Emitted when a new connection is made. -
Event: 'close'
: Emitted when the server stops accepting new connections. -
Event: 'error'
: Emitted when an error occurs.
Net.Socket
Net.Socket is a class extending
EventEmitter
and implements@@asyncIterator
.
-
connect(options)
: Opens the connection for a given socket. -
setEncoding(encoding)
: Sets the encoding for the socket. -
setTimeout(timeout)
: Sets the socket's timeout threshold when reading. -
read()
: Reads data out of the socket. -
write(data)
: Sends data on the socket. -
end(data?)
: Half-closes the socket. i.e., it sends a FIN packet. -
destroy()
: Closes and discards the TCP socket stream. -
address()
: Returns the bound address. -
remoteAddress
: The string representation of the remote IP address. -
remotePort
: The numeric representation of the remote port. -
bytesRead
: The amount of received bytes. -
bytesWritten
: The amount of bytes sent. -
Event: 'connect'
: Emitted when a socket connection is successfully established. -
Event: 'data'
: Emitted when data is received. -
Event: 'end'
: Emitted when the other end of the socket sends a FIN packet. -
Event: 'error'
: Emitted when an error occurs. -
Event: 'close'
: Emitted once the socket is fully closed. -
Event: 'timeout'
: Emitted if the socket times out from (read) inactivity.
HTTP
The HTTP package is inspired by Node.js' undici package.
-
METHODS
: A list of the HTTP methods that are supported by the parser. -
STATUS_CODES
: A collection of all the standard HTTP response status codes. -
request(url, options?)
: Performs an HTTP request.
Details
const URL = 'http://localhost:3000/foo';
const { statusCode, headers, body } = await http.request(URL);
RequestOptions
method
: (string) - Default:GET
headers
: (object) - Default:null
body
: (string | Uint8Array | stream.Readable) - Default:null
timeout
: (number) - Default:30000
(30 seconds) - Use0
to disable it entirely.throwOnError
: (boolean) - Default:false
- Whether should throw an error upon receiving a 4xx or 5xx response.
Body Mixins
The body mixins are the most common way to format the response body.
-
text()
: Produces a UTF-8 string representation of the body. -
json()
: Formats the body using JSON parsing.
Stream
Streams are very different from Node.js and are based on async-generators.
-
pipe(source, ...targets)
: An alias ofpipeline()
. -
pipeline(source, ...targets)
: Pipes between streams while forwarding errors. -
compose(...targets)
: Combines two or more streams into a Duplex stream.
Performance Measurement
-
timeOrigin
: Specifies the millisecond timestamp at which the current process began. -
now()
: Returns the millisecond timestamp, where 0 represents the start of the current process.
Assert
The assertion API is copied from: https://assert-js.norbert.tech/
-
true(value)
: Asserts that value is equal to true. -
false(value)
: Asserts that value is equal to false. -
instanceOf(value, class)
: Asserts that value is an instance of specific class. -
integer(value)
: Asserts that value is valid integer. -
number(value)
: Asserts that value is valid number (integer, float). -
oddNumber(value)
: Asserts that value is odd number. -
evenNumber(value)
: Asserts that value is event number. -
greaterThan(value, limit)
: Asserts that number is greater than. -
greaterThanOrEqual(value, limit)
: Asserts that number is greater than or equal. -
lessThan(value, limit)
: Asserts that number is less than. -
lessThanOrEqual(value, limit)
: Asserts that number is less than or equal. -
string(value)
: Asserts that value is valid string. -
boolean(value)
: Asserts that value is valid boolean. -
equal(actual, expected)
: Asserts that value is equal to expected value. -
objectEqual(actual, expected)
: Asserts that value is equal to expected value. -
object(value)
: Asserts that value is valid object. -
hasFunction(name, object)
: Asserts that object has function. -
hasProperty(name, object)
: Asserts that object has property. -
isFunction(fn)
: Asserts that value is valid function. -
array(value)
: Asserts that value is valid array. -
count(expected, arrayValue)
: Asserts that array have specific number of elements. -
notEmpty(arrayValue)
: Asserts that array is not empty. -
throws(fn, error)
: Asserts that function throws expected exception.
Contributing
Contributions are always welcome!
See CONTRIBUTING.md for ways to get started.