@volter/world-console 3.0.12 → 3.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1761,17 +1761,20 @@ function Compare({ name, token, frame, onClose, reads }: { name: string; token:
1761
1761
  const [made, setMade] = useState<string | null>(null);
1762
1762
  // the copies this panel made, kept out of the choices after they are gone (the list is read again only every so often)
1763
1763
  const mine = useRef(new Set<string>());
1764
- const branches = useDoor<{ branches: Array<{ name: string; origin?: string; at: { instant?: string; label?: string; live?: boolean } | null; expiresAt: string | null }> }>(token, `/-/${name}/branches`, reads);
1764
+ const branches = useDoor<{ branches: Array<{ name: string; origin?: string; sites?: string; at: { instant?: string; label?: string; live?: boolean } | null; expiresAt: string | null }> }>(token, `/-/${name}/branches`, reads);
1765
1765
  const choices = branches.state === 'ok' ? branches.data.branches.filter((b) => b.name !== made && !mine.current.has(b.name)) : [];
1766
1766
  // its changes, read for this comparison alone
1767
1767
  const listed = useDoor<{ total: number; acts: BoardAct[] }>(token, `/-/${name}/board/changes?frame=${encodeURIComponent(frameKey(frame))}`, reads);
1768
1768
  // a branch's page beside this World's: a site at the branch's own site address, a vendor's page on the branch's own
1769
1769
  // content plane through this World's branch door (a one-time read pass), never running on this World's origin
1770
- const pageOf = async (branch: string, origin: URL | null, isClosed: () => boolean): Promise<{ url: string } | { why: string }> => {
1770
+ const pageOf = async (branch: string, sites: string | null, isClosed: () => boolean): Promise<{ url: string } | { why: string }> => {
1771
1771
  const shown = frame.at!;
1772
1772
  if ('site' in shown) {
1773
- if (!origin) return { why: 'This World shows sites only at its own local address.' };
1774
- const u = new URL(frame.url); return { url: `${origin.protocol}//${u.hostname}.${origin.host}${u.pathname}${u.search}` };
1773
+ // the branch's site at its address, where it nests under the branch on this machine; a hosted World's sites are
1774
+ // private to its people and open through the World's own address
1775
+ const u = new URL(frame.url);
1776
+ const nested = sites && /^https?:\/\/\{host\}\./.test(sites) ? sites.replace('{host}', u.hostname.toLowerCase()) : null;
1777
+ return nested ? { url: `${nested}${u.pathname}${u.search}` } : { why: "This World shows its branches' sites only on this machine." };
1775
1778
  }
1776
1779
  const beside = `${WORLDS}/-/${name}/branches/${branch}/pages?${new URLSearchParams({ land: `/${branch}/${frame.vendor}${shown.screen}` }).toString()}`;
1777
1780
  // the door answers a navigation with the branch's address; a host that shows no content plane says so instead
@@ -1787,7 +1790,7 @@ function Compare({ name, token, frame, onClose, reads }: { name: string; token:
1787
1790
  setBefore({ state: 'opening' });
1788
1791
  const row = branches.state === 'ok' ? branches.data.branches.find((b) => b.name === base) : undefined;
1789
1792
  // a moment's wait, so passing over a branch on the way to another opens nothing
1790
- const wait = setTimeout(() => void pageOf(base, httpOrigin(row?.origin), () => closed).then((r) => { if (!closed) setBefore('url' in r ? { state: 'ok', url: r.url } : { state: 'none', why: r.why }); }), 300);
1793
+ const wait = setTimeout(() => void pageOf(base, row?.sites ?? null, () => closed).then((r) => { if (!closed) setBefore('url' in r ? { state: 'ok', url: r.url } : { state: 'none', why: r.why }); }), 300);
1791
1794
  return () => { closed = true; clearTimeout(wait); };
1792
1795
  }
1793
1796
  if (!frame.since) { setBefore({ state: 'none', why: 'Nothing here has changed since the World was last cut.' }); return; }
@@ -1798,10 +1801,10 @@ function Compare({ name, token, frame, onClose, reads }: { name: string; token:
1798
1801
  const wait = setTimeout(() => void (async () => {
1799
1802
  const r = await door(token, `/-/${name}/branches`, { method: 'POST', body: JSON.stringify({ at: { instant: at }, ttl: 3600 }), signal: AbortSignal.timeout(60000) }).catch(() => null);
1800
1803
  if (!r?.ok) { setBefore({ state: 'none', why: `The World made no copy of itself as it was then${r ? `: ${await failure(r)}` : ''}.` }); return; }
1801
- const b = (await r.json()) as { name: string; origin?: string };
1804
+ const b = (await r.json()) as { name: string; origin?: string; sites?: string };
1802
1805
  copy = b.name; setMade(b.name); mine.current.add(b.name);
1803
1806
  if (closed) { void door(token, `/-/${name}/branches/${b.name}`, { method: 'DELETE' }).catch(() => null); return; }
1804
- const page = await pageOf(b.name, httpOrigin(b.origin), () => closed);
1807
+ const page = await pageOf(b.name, b.sites ?? null, () => closed);
1805
1808
  if (!closed) setBefore('url' in page ? { state: 'ok', url: page.url, at } : { state: 'none', why: page.why });
1806
1809
  })(), 500);
1807
1810
  // the copy goes with the comparison, and with the page: a reload or a closed tab runs no cleanup of its own