d733ce3119
Wire the deferred Stage 7 surfaces end-to-end (UI -> gateway transcode -> backend REST -> existing domain services): friends (incl. one-time friend codes), per-user blocks, friend-game invitations, profile editing + email binding, the statistics screen, and the in-game history + GCG export. Friends gain two add paths (interview decision, a deliberate plan change): one-time 6-digit codes (friend_codes table, 12h TTL, single-use, rate-limited redeem); and play-gated requests (shared game required) where an explicit decline is permanent, an ignored request lapses after 30 days, and a code bypasses a decline. Migration 00006 widens friendships_status_chk and adds friend_codes. Lobby notification badge is poll + push: a new generic `notify` event drives it live; the client polls on open/focus. Language stays a single Settings control that writes through to the durable account's preferred_language. GCG export is finished-only (game.ErrGameActive) and shares/downloads the .gcg file. Tests: backend unit + inttest (friend gate/decline/code, ListInvitations, GetStats, GCG gate), gateway transcode round-trips + notify constructor, UI vitest (codecs, win-rate, share choice) + Playwright social specs. Docs: PLAN (Stage 8 done + refinements + TODO-5), ARCHITECTURE, FUNCTIONAL(+ru), UI_DESIGN, TESTING, module READMEs.
23 lines
864 B
JavaScript
23 lines
864 B
JavaScript
// Bundle-size budget gate. Sums the gzipped size of the built app JS and fails if it
|
|
// exceeds the budget — a guard against an accidental heavy dependency. The real
|
|
// transport build is ~82 KB gzip after the Stage 8 social/account/history surfaces;
|
|
// the budget leaves headroom.
|
|
import { readdirSync, readFileSync } from 'node:fs';
|
|
import { gzipSync } from 'node:zlib';
|
|
|
|
const BUDGET = 100 * 1024; // gzip bytes for app JS
|
|
const dir = 'dist/assets';
|
|
|
|
let total = 0;
|
|
for (const f of readdirSync(dir)) {
|
|
if (!f.endsWith('.js')) continue;
|
|
const gz = gzipSync(readFileSync(`${dir}/${f}`)).length;
|
|
total += gz;
|
|
console.log(`${f}: ${(gz / 1024).toFixed(1)} KB gzip`);
|
|
}
|
|
console.log(`total app JS: ${(total / 1024).toFixed(1)} KB gzip (budget ${BUDGET / 1024} KB)`);
|
|
if (total > BUDGET) {
|
|
console.error('bundle exceeds size budget');
|
|
process.exit(1);
|
|
}
|