JS.Popcorn (Popcorn v0.4.0-next.3)

View Source

A BEAM VM in a browser worker.

Use Popcorn.init to create and start an instance.

Summary

Functions

Starts the VM and waits for its bridge and entrypoint application.

Stops the worker and completes pending sends and calls with vm:exited.

Creates an instance and waits for boot.

Registers a handler for BEAM message payloads.

Creates the worker.

Sends new terminal dimensions to a booted VM.

Sends a payload to a registered process name or a Pid from this VM boot.

Queues terminal input.

Properties

genserver

@spec readonly genserver: GenServer

JS.Popcorn.Genserver

Functions

async boot()

@spec async boot(): Promise<Result<Popcorn<Output>>>

Starts the VM and waits for its bridge and entrypoint application.

Without an entrypoint, waits only for the bridge.

After shutdown, starts a fresh VM with the original options.

Returns

Ok tuple with this if boot completes or error tuple.

Example

const popcorn = new Popcorn({});
popcorn.onEvent((message) => console.log(message));
const result = await popcorn.boot();
if (!result.ok) throw result.error;

deinit(reason = ...)

@spec deinit(reason: VmExitReason = ...): void

Stops the worker and completes pending sends and calls with vm:exited.

Releases tracked values and runs their cleanup callbacks. Keeps event handlers for the next boot. Repeated calls have no effect.

async init(opts = {})

@spec async init<Output>(opts: PopcornOpts<Output> = {}): Promise<Result<Popcorn<Output>>>

Creates an instance and waits for boot.

For startup messages, use the constructor and register onEvent before boot.

Returns

Ok tuple or runtime:eval-unavailable if the page blocks JavaScript evaluation.

onEvent(handler)

@spec onEvent(handler: (event: unknown) => void): () => void

Registers a handler for BEAM message payloads.

Messages with no handlers are lost. Startup messages can arrive before boot resolves. VM errors and terminal output use the callbacks in PopcornOpts.

Returns

a function that removes the handler.

Popcorn(opts = {})

@spec Popcorn<Output>(opts: PopcornOpts<Output> = {}): Popcorn<Output>

Creates the worker.

Call boot to start the VM.

resizeTty(columns, rows)

@spec resizeTty(columns: number, rows: number): Result<null>

Sends new terminal dimensions to a booted VM.

Each dimension must be between 1 and 65,535.

async send(rawTarget, payload?)

@spec async send(rawTarget: string | Pid, payload?: unknown): Promise<Result<null>>

Sends a payload to a registered process name or a Pid from this VM boot.

The process receives {wasm, Payload}. A send timeout does not cancel delivery. Uses the value conversions in AnyValue. An omitted, null, or undefined payload becomes an empty map.

Returns

Ok tuple or bridge:not-started before boot and vm:exited after shutdown.

Example

Send an Erlang {ok, <<"value">>} tuple to a registered receiver process.

const result = await popcorn.send("receiver", tuple(atom("ok"), "value"));
if (!result.ok) throw result.error;

See

writeStdin(chunk)

@spec writeStdin(chunk: string | Uint8Array<ArrayBufferLike>): Result<null>

Queues terminal input.

Encodes strings as UTF-8 and copies byte arrays. Does not append a newline.

Returns stdio:overflow if the chunk exceeds the remaining 64 KiB queue capacity. An overflow leaves the queue unchanged.