dartway_studio_bridge 0.3.0 copy "dartway_studio_bridge: ^0.3.0" to clipboard
dartway_studio_bridge: ^0.3.0 copied to clipboard

Open bridge between a DartWay app and DartWay Studio: in-code screen spec registry models and the runtime postMessage protocol.

DartWay Studio Bridge #

The open bridge between a DartWay app and DartWay Studio: screen specs declared in the app's code plus a versioned postMessage protocol that lets Studio preview, navigate and drive a running web build of the app.

The app is the single source of truth for its structure: Studio receives the manifest (navigation zones, screen passports, supported locales) over the runtime channel on connect, so it can never go stale relative to the running build. Demo personas are the opposite — a platform concern: test users and their codes are configured in Studio and never ship inside the app's public web build. Studio signs in by sending the credentials to the app, which runs its regular auth flow with them.

Declaring specs (app side) #

Passport texts are plain strings — write them in whatever language your team works in; Studio shows them as is.

final scheduleSpec = StudioScreenSpec(
  path: '/schedule',
  title: 'Schedule',
  purpose: 'Weekly class timetable...',
  discussionQuestions: ['Should slots be bookable here?'],
);

final manifest = StudioProjectManifest(
  projectName: 'My App',
  zones: [
    StudioZoneSpec(
      label: 'Client app',
      rootPath: '/schedule',
      access: StudioZoneAccess.signedIn,
      screens: [scheduleSpec /* ... */],
    ),
    StudioZoneSpec(
      label: 'Admin',
      rootPath: '/admin',
      access: StudioZoneAccess.signedIn,
      // Role-gating is the app's own job (router guards, server filters) —
      // the zone spec only says a session is needed at all.
      screens: [/* ... */],
    ),
  ],
  // The app's full feature catalog — Studio diffs it against its records on
  // connect. DartWay apps map their feature-registry enum onto StudioFeatureInfo.
  features: [/* StudioFeatureInfo(id: 'chats/list', title: ..., description: ...) */],
  // Declare two or more locales to get a locale switcher in Studio; the app
  // executes the switch itself via StudioBridgeHostDelegate.onLocaleRequest.
  supportedLocales: ['en', 'ru'],
);

Attaching the host (app side) #

final host = StudioBridgeHost.attach(
  manifest: manifest,
  delegate: myDelegate, // navigate / sign-in with credentials / sign-out / locale
  currentPath: () => router.currentPath,
  currentSession: () => mySessionState,
  currentLocale: () => myLocale.languageCode, // omit if not localized
  // Accept only a Studio that presents this project's secret. The build bakes
  // only the secret's HASH; the secret itself stays in Studio.
  validateAccessKey: studioHashAccessValidator(
    const String.fromEnvironment('STUDIO_KEY_HASH'),
  ),
);
host?.reportRoute(newPath, routeName: 'scheduleList'); // on router changes
host?.reportSession(newState);  // on auth changes
host?.reportLocale(newLocale);  // on locale changes

attach returns null when the app is not running on web inside an iframe — the app stays fully functional and the bridge dormant. The channel pins the origin of the first valid Studio message for its replies.

Access control. The studioConnect handshake carries an accessKey; the host answers with its manifest only if validateAccessKey accepts it, otherwise it stays silent (Studio shows "not connected"). The bridge is agnostic to how you check — the shipped studioHashAccessValidator(hash) keeps the secret out of the public build: Studio holds a per-project random secret, the app bakes only its hash (studioAccessKeyHash, hex SHA-256) and compares. An empty expected hash accepts any key (zero-config local dev).

Connecting (Studio side) #

final controller = createStudioFrameController(appUrl: 'http://localhost:8091/');
final client = StudioBridgeClient(
  channel: controller.channel,
  accessKey: project.accessSecret, // the raw secret; the app checks its hash
)..start();
// render: HtmlElementView(viewType: controller.viewType)
client.events.listen(...); // connected / route / session / locale changed
client.requestNavigation('/schedule');
client.requestLocale('ru');

The handshake is dual-initiated and survives reloads and hot restarts of either side. Protocol details live in StudioBridgeProtocol.

0
likes
0
points
319
downloads

Publisher

verified publisherdartway.dev

Weekly Downloads

Open bridge between a DartWay app and DartWay Studio: in-code screen spec registry models and the runtime postMessage protocol.

Homepage
Repository (GitHub)
View/report issues

Topics

#dartway #flutter #tooling #preview

License

unknown (license)

Dependencies

crypto, flutter, web

More

Packages that depend on dartway_studio_bridge