Chasing MasteryDevelopers
Packages and Practice Modes
Chasing Mastery public platform

Input and package-owned UI

Build a simple host form or a rich portable player, and make every evidence path converge on one domain reducer.

Choose the lightest honest input

Use a host-rendered declarative form for one bounded submission: a score, time, percentage, pass/not-yet result, short text, or a small fixed set of fields.

Use a portable web_ui player when an Attempt needs:

  • several actions over time;
  • a board, map, puzzle, route, or spatial control;
  • intermediate state or contextual instructions;
  • live automatic observations;
  • correction controls;
  • custom animation or rich visual feedback.

The same immutable player runs inside a browser iframe and native WebView.

The bridge

Prop

Type

Create it with createPortablePackageUiBridge. The bridge validates and bounds every message and tolerates both browser and native delivery semantics.

import { createPortablePackageUiBridge } from "@chasingmastery/sdk";

const bridge = createPortablePackageUiBridge();
const unsubscribe = bridge.subscribe((message) => {
  if (message.type === "snapshot") render(message.snapshot);
  if (message.type === "command_result") reconcile(message);
});

bridge.send({ type: "snapshot_request" });

The player sends only declared intents. The host adds actor, route, trusted time, expected revision, and idempotency before invoking package behavior.

Lifecycle requirements

A production player must handle:

  • loading before the first authoritative snapshot;
  • active interaction;
  • a command pending while the UI remains understandable;
  • repeated taps without duplicate application;
  • reconnect and foreground recovery;
  • automatic-input healthy, stale, unavailable, and fallback states;
  • terminal result and read-only replay;
  • reduced motion, keyboard input, 200% text, and safe touch targets;
  • iframe and WebView viewport changes.

The host owns Close, retry of host loading, and generic terminal navigation. The package owns the activity-specific result meaning and “Practice again” intent.

Manual and automatic equivalence

manual: tap “Treble 20” → command → normalized throw
auto: AutoDarts payload → exact observation → normalized throw

                                      one Darts reducer

Workbench should run both paths against the same scenario and compare final state, Measurements, Story Events, and presentation. Automatic input is an enhancement, not an excuse to leave manual mode broken.

Security constraints

Portable UI cannot request arbitrary fetch, storage, file, camera, microphone, OBS, clipboard, identity, or account operations. A new bridge message is a new public capability and requires schema limits, host authorization, fixtures, and conformance—not an untyped escape hatch.

On this page