mirror of
https://github.com/garrytan/gstack.git
synced 2026-06-04 00:58:04 +02:00
refactor(design): board JS uses relative paths; drop __GSTACK_SERVER_URL injection
Board JS in design/src/compare.ts now calls ./api/feedback and ./api/progress (relative to location.pathname) and feature-detects server mode via location.protocol instead of the injected window.__GSTACK_SERVER_URL global. The injection in design/src/serve.ts is removed (dead code now that nothing reads it). Tests updated to match the new contract: serve.test.ts asserts the relative-path JS is present and the global is gone; feedback-roundtrip asserts location.protocol detects HTTP mode. Why: prep for the multi-board daemon (design/src/daemon.ts upcoming) where the same generated HTML is served at /boards/<id>/ instead of /. Relative paths resolve against location.pathname in both cases, so one HTML, two hosts. The injection was the only thing tying board JS to a specific serving path; removing it unblocks the daemon work without forking the generator. file:// fallback preserved via the location.protocol feature-detect — board opened directly as a file still falls through to the DOM-only success path. The 6 feedback-roundtrip browser tests continue to fail with session.clearLoadedHtml undefined; that failure pre-exists this branch (verified against HEAD with these edits stashed) and lives in browse/src/write-commands.ts, not in the design code path. Tracking separately. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -55,7 +55,7 @@ beforeAll(async () => {
|
||||
serverState = 'serving';
|
||||
|
||||
// This server mirrors the real serve.ts behavior:
|
||||
// - Injects __GSTACK_SERVER_URL into the HTML
|
||||
// - Serves board HTML at / (board JS uses relative URLs)
|
||||
// - Handles POST /api/feedback with file writes
|
||||
// - Handles GET /api/progress for regeneration polling
|
||||
// - Handles POST /api/reload for board swapping
|
||||
@@ -67,11 +67,7 @@ beforeAll(async () => {
|
||||
const url = new URL(req.url);
|
||||
|
||||
if (req.method === 'GET' && (url.pathname === '/' || url.pathname === '/index.html')) {
|
||||
const injected = currentHtml.replace(
|
||||
'</head>',
|
||||
`<script>window.__GSTACK_SERVER_URL = '${url.origin}';</script>\n</head>`
|
||||
);
|
||||
return new Response(injected, {
|
||||
return new Response(currentHtml, {
|
||||
headers: { 'Content-Type': 'text/html; charset=utf-8' },
|
||||
});
|
||||
}
|
||||
@@ -140,14 +136,15 @@ describe('Submit: browser click → feedback.json on disk', () => {
|
||||
if (fs.existsSync(feedbackPath)) fs.unlinkSync(feedbackPath);
|
||||
serverState = 'serving';
|
||||
|
||||
// Navigate to the board (served with __GSTACK_SERVER_URL injected)
|
||||
// Navigate to the board (board JS uses relative URLs + location.protocol detect)
|
||||
await handleWriteCommand('goto', [baseUrl], bm);
|
||||
|
||||
// Verify __GSTACK_SERVER_URL was injected
|
||||
const hasServerUrl = await handleReadCommand('js', [
|
||||
'!!window.__GSTACK_SERVER_URL'
|
||||
// Verify the board detects HTTP mode (so postFeedback will actually fetch
|
||||
// instead of falling into the file:// DOM-only path)
|
||||
const httpDetected = await handleReadCommand('js', [
|
||||
"location.protocol === 'http:' || location.protocol === 'https:'"
|
||||
], bm);
|
||||
expect(hasServerUrl).toBe('true');
|
||||
expect(httpDetected).toBe('true');
|
||||
|
||||
// User picks variant A, rates it 5 stars
|
||||
await handleReadCommand('js', [
|
||||
|
||||
@@ -65,11 +65,9 @@ describe('Serve HTTP endpoints', () => {
|
||||
const url = new URL(req.url);
|
||||
|
||||
if (req.method === 'GET' && url.pathname === '/') {
|
||||
const injected = htmlContent.replace(
|
||||
'</head>',
|
||||
`<script>window.__GSTACK_SERVER_URL = '${url.origin}';</script>\n</head>`
|
||||
);
|
||||
return new Response(injected, {
|
||||
// Board JS uses relative URLs (./api/feedback, ./api/progress)
|
||||
// and a location.protocol feature-detect; no injection needed.
|
||||
return new Response(htmlContent, {
|
||||
headers: { 'Content-Type': 'text/html; charset=utf-8' },
|
||||
});
|
||||
}
|
||||
@@ -118,12 +116,17 @@ describe('Serve HTTP endpoints', () => {
|
||||
server.stop();
|
||||
});
|
||||
|
||||
test('GET / serves HTML with injected __GSTACK_SERVER_URL', async () => {
|
||||
test('GET / serves HTML with relative-path board JS (no injection)', async () => {
|
||||
const res = await fetch(baseUrl);
|
||||
expect(res.status).toBe(200);
|
||||
const html = await res.text();
|
||||
expect(html).toContain('__GSTACK_SERVER_URL');
|
||||
expect(html).toContain(baseUrl);
|
||||
// No more per-origin URL injection; board JS uses relative paths.
|
||||
expect(html).not.toContain('__GSTACK_SERVER_URL');
|
||||
expect(html).not.toContain(baseUrl);
|
||||
// Board JS calls relative endpoints so the same HTML works at / and at
|
||||
// /boards/<id>/ (daemon mode).
|
||||
expect(html).toContain("fetch('./api/feedback'");
|
||||
expect(html).toContain("fetch('./api/progress')");
|
||||
expect(html).toContain('Design Exploration');
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user