The 35 files behind twelve public pages, seven admin views, two player views and three core-page extensions, ported onto `window.__rg`. Every one of them imports exactly the seven kit members plus `lib/format.js`, which is the finding §2.7.1 predicted and this confirms. `client/src/core.js` is the port mechanism, and unlike the server's it is a plain read: `window.__rg` is published before any module chunk evaluates, so there is no gap to defer around and a ported component keeps its ordinary import shape. `client/src/api.js` rebuilds the UO namespaces over the request primitive — same URLs, because §1.2 freezes the API surface. SPA paths changed and API paths did not. `/site/shard` is `/uo/shard`, and the admin paths lost their now-redundant `shard-` prefixes (`/admin/uo/ops`), a clean break being the only moment that is free. `shim/rg.js` becomes the single reader of the global, so the "core did not publish its dependencies" message is reachable from whichever module the bundler happens to touch first rather than from whichever one is imported first — a guarantee that used to last until someone sorted the imports. Co-Authored-By: Claude <noreply@anthropic.com>
52 lines
2.3 KiB
JavaScript
52 lines
2.3 KiB
JavaScript
import { useEffect } from 'react'
|
|
import api from '../api.js'
|
|
import { useGameAccountSignup } from '../lib/useShardFeatures.js'
|
|
import CreateGameAccountForm from './CreateGameAccountForm.jsx'
|
|
|
|
// ── This module's fill for the `player.invite.accepted` slot ───────────────
|
|
//
|
|
// Core's invite-acceptance page (`routes/player/AcceptInvite.jsx`) used to render
|
|
// this step itself: it read `gameAccountSignup` out of core's public settings and
|
|
// posted to `api.player.shard.createAccount`. Both of those are ours, and the
|
|
// page they sat on is not — an invite is a core concept and staff get invited
|
|
// too. So slice 3 declared a third extension slot rather than moving the page or
|
|
// leaving core importing a module component. MODULE_API.md §3.7.
|
|
//
|
|
// **The whole decision about whether there is a step at all is on this side.**
|
|
// Core renders the shell and a "skip" control whenever the slot is filled, and
|
|
// hands us `onDone`. If this shard does not offer website-created game accounts
|
|
// there is nothing to do here, so we call `onDone` and the invitee goes straight
|
|
// to the portal — which is exactly what core's own code did when the flag was
|
|
// off, only now the flag is not core's to read.
|
|
//
|
|
// The spinner while the answer is in flight is the honest cost of that split: the
|
|
// invitee sees core's chrome for one cached request before this either renders or
|
|
// stands aside. Rendering the form optimistically and retracting it would be
|
|
// worse, and asking core to wait on a module before painting would put a module's
|
|
// latency in front of a core page.
|
|
export default function InviteGameAccountStep({ onDone }) {
|
|
const signupOk = useGameAccountSignup()
|
|
|
|
useEffect(() => {
|
|
if (signupOk === false) onDone()
|
|
}, [signupOk, onDone])
|
|
|
|
// `null` is "not yet", not "no" — see useGameAccountSignup.
|
|
if (signupOk !== true) {
|
|
return (
|
|
<div style={{ display: 'grid', placeItems: 'center', padding: 20 }}>
|
|
<span className="spin" />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<p className="sans" style={{ marginTop: 0, color: 'var(--muted)', fontSize: '0.9rem', lineHeight: 1.6 }}>
|
|
Your account is ready. Create a game account now to play, or skip and do it later from your portal.
|
|
</p>
|
|
<CreateGameAccountForm submit={api.player.shard.createAccount} onCreated={onDone} />
|
|
</>
|
|
)
|
|
}
|