waybetter/packages/runtime/src/accountReport.ts
CRTkafa 41267a22fd Extract the wayBetter framework core from wayBetter for X
Site-agnostic parts of the X app, behind a small site adapter:

- crates/waybetter-host: webview-label security policy and tab rect
  clamp, account profiles with native-owned accounts (AccountRules),
  plugin store with bundled-plugin upgrades (PluginHost), signed
  data-only hotfix channel, update scheduling and crash handshake, tab
  payloads/link routing/tab-chrome validation, and (feature "tauri")
  webview helpers and the Windows system menu.
- packages/runtime: DOM hub, request hub, plugin API core, OKLab theme
  color model, split-view rail hiding, link routing and account
  reporting, each configured by a SiteAdapter.
- packages/shell: address bar, pane, link-drop, profile, palette and
  update-chip models, and window controls with the Tauri API injected.

Tests moved/adapted from the app: 45 Rust (headless), 40 TypeScript.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 03:01:33 +07:00

35 lines
1.5 KiB
TypeScript

// Tells the app which account is signed in inside this tab's profile, so the account switcher
// lists real logins (avatar, name, handle) instead of hand-named slots. Read from the site's own
// UI, which the site renders anyway; nothing is requested. Only a change is reported (`tab_report`),
// and native code accepts it only from a webview that is on the site, for that webview's own profile.
import { watchDom } from './domHub.ts';
export type SeenAccount = { handle: string; name: string; avatar: string | null };
export type AccountReport = { account: SeenAccount } | { signedOut: true };
export type AccountSite = {
/** The account the site's UI shows, or null when there is none (yet). Pure over the DOM. */
read(root: ParentNode): SeenAccount | null;
/** The site shows its signed-out page. */
signedOut(root: ParentNode): boolean;
};
export type Invoke = (command: string, args: Record<string, unknown>) => Promise<unknown>;
export function installAccountReport(win: Window, site: AccountSite, invoke?: Invoke) {
if (!invoke) return { dispose() {} };
let last = '';
const send = (report: AccountReport) => {
const key = JSON.stringify(report);
if (key === last) return;
last = key;
invoke('tab_report', { report }).catch(() => { last = ''; });
};
const check = () => {
const account = site.read(win.document);
if (account) send({ account });
else if (site.signedOut(win.document)) send({ signedOut: true });
};
return watchDom(win as unknown as Parameters<typeof watchDom>[0], check);
}