JavaScript API
This document provides a guide to the pie-client
library, an asynchronous client for interacting with the Pie from Node.js or a web browser. It allows you to upload and manage WebAssembly programs on a remote server.
npm install pie-client
In a browser, you can use a bundler like Webpack or Rollup, or include the scripts directly.
Quick Start
Here’s a complete example demonstrating a typical workflow: connecting to the server, uploading a program, launching it, and processing its events.
import { PieClient } from './pie-client.js'; // Adjust path as needed
import { blake3 } from 'blake3';
import { TextEncoder } from 'util'; // In Node.js
async function main() {
const client = new PieClient("ws://127.0.0.1:8080");
try {
// Establish the connection to the server
await client.connect();
const programBytes = ...
const programHash = blake3(programBytes).toString('hex');
console.log(`Uploading program with hash: ${programHash}`);
await client.uploadProgram(programBytes);
// 3. Launch the program as a new instance
console.log("Launching instance...");
const instance = await client.launchInstance(programHash);
console.log(`Instance launched with ID: ${instance.instanceId}`);
// 4. Listen for events from the instance
while (true) {
const { event, msg } = await instance.recv();
console.log(`Received Event: '${event}', Message: '${msg}'`);
// Check for terminal events to break the loop
if (['Completed', 'Aborted', 'Exception'].includes(event)) {
console.log("Instance has terminated.");
break;
}
}
} catch (error) {
console.error("An error occurred:", error);
} finally {
// 5. Ensure the client connection is closed
console.log("Closing client connection.");
await client.close();
}
}
main();
PieClient
Class
The PieClient
is the primary interface for server communication. It manages the WebSocket connection, authentication, and program lifecycle.
Initialization
class PieClient {
/**
* @param {string} serverUri The WebSocket URI of the Pie server.
*/
constructor(serverUri)
}
Usage:
const client = new PieClient("ws://localhost:8080");
Connection Management
You must explicitly connect before performing other operations and close the connection when finished. A try...finally
block is recommended to ensure close()
is always called.
connect
Establishes the WebSocket connection.
/**
* @returns {Promise<void>} A promise that resolves when connected.
*/
async connect()
close
Gracefully closes the connection.
/**
* @returns {Promise<void>} A promise that resolves when the connection is closed.
*/
async close()
Methods
authenticate
Authenticates the client session using a token.
/**
* @param {string} token The authentication token.
* @returns {Promise<{successful: boolean, result: string}>}
*/
async authenticate(token)
uploadProgram
Uploads a compiled WASM program to the server. The data is sent in chunks.
/**
* @param {Uint8Array} programBytes The program content as a byte array.
* @returns {Promise<void>}
*/
async uploadProgram(programBytes)
launchInstance
Starts a new instance of a previously uploaded program.
/**
* @param {string} programHash The blake3 hash of the program to launch.
* @param {string[]} [args=[]] Optional command-line arguments for the instance.
* @returns {Promise<Instance>} A promise that resolves with an Instance object.
*/
async launchInstance(programHash, args = [])
Instance
Class
The Instance
object represents a single running program on the server. It is returned by PieClient.launchInstance()
and provides methods for direct interaction.
Methods
send
Sends a string message to the instance.
/**
* @param {string} message The string message to send.
* @returns {Promise<void>}
*/
async send(message)
recv
Waits for and receives the next event from the instance. This is an asynchronous, blocking call.
/**
* @returns {Promise<{event: string, msg: (string|Uint8Array)}>}
*/
async recv()
- Returns: A promise that resolves to an object with two properties:
event
: A string representing the event type (see Event Types below).msg
: The message payload. This is astring
for most events or aUint8Array
for aBlob
event.
terminate
Sends a fire-and-forget request to terminate the instance.
/**
* @returns {Promise<void>}
*/
async terminate()
Event Types
The event
string returned by instance.recv()
can be one of the following values, corresponding to the server's Event
enum.
'Message'
: Standard output (stdout) from the instance. Themsg
property is a string.'Blob'
: The instance has sent a binary data blob. Themsg
property is aUint8Array
.'Completed'
: The instance finished successfully (exit code 0).'Aborted'
: The instance terminated with a non-zero exit code.'Exception'
: An internal WASM trap or exception occurred in the instance.'ServerError'
: The server encountered an error managing the instance.'OutOfResources'
: The instance was terminated for exceeding resource limits.