Runtime Contract

This document defines the modern runtime contract for this.gui.

The current direction is:

1. Runtime Sources

When you call mount() directly inside a modern ESM app, pass the package surface and React namespaces explicitly:

import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import * as GUI from 'this.gui';

this.GUI can render in three modes:

Static UI

import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import * as GUI from 'this.gui';
import { mount } from 'this.gui/runtime';

mount(
  {
    type: 'Page',
    props: { title: 'Static' },
    children: [{ type: 'Typography', props: { children: 'No runtime needed.' } }],
  },
  '#root',
  { gui: GUI, React, ReactDOM }
);

Custom runtime adapter

import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import * as GUI from 'this.gui';
import { mount } from 'this.gui/runtime';

const runtime = {
  resolve(value: any) {
    return value;
  },
  action(_expression: string) {
    return () => {};
  },
};

mount(spec, '#root', { gui: GUI, React, ReactDOM, runtime });

.me runtime

import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import * as GUI from 'this.gui';
import ME from 'this.me';
import { createMeRuntime, mount } from 'this.gui/runtime';

const me = new ME();
me.profile.name('Ana');
const runtime = createMeRuntime(me);

mount(spec, '#root', { gui: GUI, React, ReactDOM, me, runtime });

When me is passed, this.gui can derive the runtime adapter automatically. For mixed React + mounted-spec screens, sharing an explicit runtime is the recommended path.

.me runtime, live over a network monad

createMeRuntime() above is local-only — me is an in-memory kernel with no network awareness. createWsMeRuntime() is a drop-in RuntimeAdapter for talking to a remote monad instead: reads/writes go over HTTP, and subscribe/getSnapshot ride a /nrp WebSocket connection, so useMeValue/{ read: ... } tokens reflect writes made by other connected clients — no polling.

import ME from 'this.me';
import { createWsMeRuntime, mount } from 'this.gui/runtime';

const me = new ME();
const runtime = createWsMeRuntime(me, {
  semanticNamespace: 'myapp.mymachine.local',
  transportOrigin: 'http://local.netget/apps/myapp',
});

mount(spec, '#root', { gui: GUI, React, ReactDOM, me, runtime });

Two things this doesn’t do automatically:

2. React Bridge

When your host app is React, use this.gui/react.

import ME from 'this.me';
import { MeRuntimeProvider, useMeAction, useMeValue } from 'this.gui/react';

const me = new ME();

function ProfileName() {
  const name = useMeValue<string>('profile.name');
  const setName = useMeAction('profile.name');

  return (
    <button onClick={() => setName('Ana')}>
      {name}
    </button>
  );
}

export default function App() {
  return (
    <MeRuntimeProvider me={me}>
      <ProfileName />
    </MeRuntimeProvider>
  );
}

Contract:

3. Read / Write Tokens

Dynamic spec props are expressed as tokens:

Legacy aliases still work:

Example:

{
  "type": "Button",
  "props": {
    "label": { "read": "me/profile/name" },
    "onClick": { "write": "me/profile/status = 'offline'" }
  }
}

Notes:

Examples:

{
  "type": "Typography",
  "props": {
    "children": { "read": "me/shops//name" }
  }
}

4. Router Contract

Router supports:

Resolved params are injected into ctx.params.

import { Router } from 'this.gui';

const router = new Router({ runtime });

router.set('/dashboard', () => ({
  type: 'Page',
  props: { title: 'Dashboard' },
}));

router.set('/shops/:id', ({ ctx }) => ({
  type: 'Page',
  props: {
    title: { read: 'me/shops//name' },
    subtitle: `shop id=${ctx.params.id}`,
  },
}));

Behavior:

5. Security Defaults

Runtime expressions are deny-by-default unless they match an allowed root.

Current default roots:

You can extend them:

mount(spec, '#root', {
  gui: GUI,
  React,
  ReactDOM,
  me,
  allowedExprRoots: ['me/', 'me://', 'self:', 'kernel:'],
});

Or disable the allowlist entirely for trusted environments:

mount(spec, '#root', {
  gui: GUI,
  React,
  ReactDOM,
  me,
  unsafeAllowAllExpressions: true,
});

6. Devtools Contract

Devtools are now opt-in.

mount(spec, '#root', {
  gui: GUI,
  React,
  ReactDOM,
  me,
  devtools: {
    inspector: false,
    inspectorToggleVisible: true,
    adminView: false,
  },
});

Recommended rule:

For direct imports, use this.gui/devtools.

7. Package Boundaries

modern boundaries: