@textmode/runner-client
v0.6.0
Published
Browser iframe runtime client for the hosted textmode runner.
Readme
@textmode/runner-client
| |
|
|
|:-------------|:-------------|:-------------|
@textmode/runner-client is a browser iframe runtime client for the hosted
textmode.js runner. It
gives any browser host app a typed runtime API for mounting the runner iframe,
performing the generic protocol handshake, routing request/response messages,
monitoring heartbeat status, running code, reconnecting, and disposing the
transport.
Use it to embed the sandboxed runner at runner.textmode.art
from your own host app. It does not execute textmode.js sketches directly; it
controls a runner app at the runnerUrl you provide.
Features
- Typed runtime API - Mount, run, reconnect, and dispose the runner through
one
IframeTextmodeRuntimeinstance. - Sandboxed iframe - Mounts the runner under a minimal iframe sandbox and
refuses unsafe
allow-scriptsplusallow-same-origincombinations on the parent origin. - Request/response routing - Matches
runCodeand other requests to their responses across theMessagePorttransport. - Heartbeat monitoring - Reports runner liveness and status for host UI state.
- In-place runtime resets -
resetRuntimerebuilds the textmode runtime without replacing the iframe document or transport. - WebKit activation handling - Surfaces
USER_ACTIVATION_REQUIREDso hosts can expose the frame for a trusted child-frame interaction.
Installation
npm install @textmode/runner-client@textmode/runner-protocol is installed as a dependency and is also available
for consumers that need the protocol types directly.
Usage
import {
IframeTextmodeRuntime,
RunnerRequestError,
type RunnerRuntimeStatus,
} from '@textmode/runner-client';
const container = document.querySelector<HTMLElement>('#runner');
if (!container) {
throw new Error('missing runner container');
}
const runtime = new IframeTextmodeRuntime({
runnerUrl: 'https://runner.textmode.art/',
onUserActivationRequired() {
container.dataset.userActivation = 'required';
},
onUserInteraction() {
delete container.dataset.userActivation;
},
onStatusChange(status: RunnerRuntimeStatus, reason) {
console.info('runner status changed', status, reason);
},
});
await runtime.init(container);
try {
await runtime.runCode(`
t.draw(() => {
t.print('textmode', 0, 0);
});
`);
} catch (error) {
if (error instanceof RunnerRequestError) {
console.error(error.message, error.line, error.column);
}
}
runtime.dispose();Public API
Import from the package root only:
import { IframeTextmodeRuntime } from '@textmode/runner-client';Public subpath imports are intentionally not supported. Internal modules such as request routing, heartbeat control, iframe mounting, and sandbox policy may change without a semver-major release.
The main exports are:
IframeTextmodeRuntimeRunnerRuntimeStatusRunnerExecutionErrorRunnerRequestErrorIframeTextmodeRuntimeOptionsIframeMountModeIframeSandboxTokenDEFAULT_IFRAME_SANDBOX_TOKENS
Runtime Lifecycle
Typical host apps follow this lifecycle:
- Create an
IframeTextmodeRuntimewith a trustedrunnerUrl. - Call
init(container)from a browser context. - Use
runCodeto replace the current sketch execution while preserving its timeline. - Use
resetRuntimeto rebuild textmode while preserving the current iframe document and its browser interaction state. - Call
reconnectonly when the iframe document or transport must be replaced. - Call
disposewhen the host view is unmounted.
resetRuntime falls back to reconnecting when an older runner does not
advertise the optional runtimeReset capability.
Cross-origin WebKit runners may request one trusted child-frame interaction
through onUserActivationRequired. A host can temporarily expose or elevate
the existing iframe until onUserInteraction fires. Programmatic focus or a
synthetic parent-page click is not an equivalent substitute.
The runtime exposes status, isReady, and frame getters for host UI state.
Sandbox Policy
The default iframe sandbox tokens are:
['allow-scripts', 'allow-same-origin']allow-downloads is not included by default. Sketches can use the installed
textmode.export.js helpers inside the sandboxed runtime, but the host client
does not expose a parent-controlled export channel.
The runtime refuses to start a runner that combines allow-scripts and
allow-same-origin on the same origin as the parent page.
Related packages
@textmode/runner-client works with the following packages in this repository:
| Package | Relationship |
| -------------------------------------------------------------------- | ------------------------------------------------- |
| @textmode/runner-protocol | The wire contract this client speaks |
| @textmode/runner-app | The sandboxed runner app this client controls |
Next steps
- Read the runner overview for the workspace conventions.
- Browse all packages to find related runner packages.
- Browse the API docs for the generated type reference.
- Visit code.textmode.art for the ecosystem documentation.
License
The @textmode/runner-client package is licensed under the AGPL-3.0-or-later License.
