chore: remove legacy Windows launcher and PORTABLE verification records

Storybook is served on the web (main deployment), so the Windows BAT
launcher and its Node helper are no longer used. The root PORTABLE
r4-r6 verification records are historical ZIP-era notes that nothing
references.

- Delete start-storybook.bat and scripts/start-storybook.mjs
- Delete PORTABLE-R4/R5-CANDIDATE/R5/R6-VERIFICATION.md
- README, publisher distribution guide, LAN preview note: point to the
  web Storybook; keep npm run storybook for local development
- v2 baseline report: unlink the removed files, keep the record text
This commit is contained in:
shkim4 committed 2026-10-22 09:31:58 +09:00
1 parent 10a1dcd28f
commit f8cb5f8318
10 files changed
+10 -280

No files matched your search

-84
View File
@@ -1,84 +0,0 @@
// Git source launcher. Uses the existing npm scripts; no portable runtime.
import { spawn } from 'node:child_process';
import { readFileSync, existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import net from 'node:net';
process.chdir(fileURLToPath(new URL('../', import.meta.url)));
const pkg = JSON.parse(readFileSync('package.json', 'utf8'));
const portMatch = pkg.scripts?.storybook?.match(/(?:-p|--port)\s+(\d+)/);
if (!portMatch) throw new Error('Cannot determine the port from package.json scripts.storybook.');
const port = Number(portMatch[1]);
const url = `http://localhost:${port}/`;
const [major, minor] = process.versions.node.split('.').map(Number);
if (!((major === 20 && minor >= 19) || (major === 22 && minor >= 12) || major > 22)) {
throw new Error('Node.js 20.19+ (20.x) or 22.12+ is required by the lockfile.');
}
function run(args, options = {}) {
return spawn(process.env.ComSpec || 'cmd.exe', ['/d', '/s', '/c', args], {
stdio: 'inherit', windowsHide: true, ...options,
});
}
function completed(child) {
return new Promise((resolve, reject) => {
child.once('error', reject);
child.once('exit', (code) => code === 0 ? resolve() : reject(new Error(`Command failed with exit code ${code}. See output above.`)));
});
}
async function ready() {
try {
const response = await fetch(`${url}index.json`, { signal: AbortSignal.timeout(1500) });
if (!response.ok) return false;
const index = await response.json();
if (!index.entries?.['components-form-button--all'] || !index.entries?.['theme-designer-playground--editor']) return false;
return (await fetch(`${url}iframe.html`, { signal: AbortSignal.timeout(1500) })).ok;
} catch { return false; }
}
function occupied() {
return new Promise(resolve => {
const socket = net.connect({ host: '127.0.0.1', port });
socket.setTimeout(1500);
socket.once('connect', () => { socket.destroy(); resolve(true); });
socket.once('error', () => { socket.destroy(); resolve(false); });
socket.once('timeout', () => { socket.destroy(); resolve(true); });
});
}
async function openBrowser() {
await completed(spawn('powershell.exe', ['-NoProfile', '-NonInteractive', '-Command', `Start-Process '${url}'`], {
stdio: 'inherit', windowsHide: true,
}));
}
if (await ready()) {
await openBrowser();
} else {
if (await occupied()) throw new Error(`Port ${port} is occupied by a server that is not a ready HMDesign Storybook. Stop it and retry.`);
await completed(run('npm.cmd --version', { stdio: 'ignore' }));
if (!existsSync('node_modules/.bin/storybook.cmd')) await completed(run('npm.cmd ci'));
const missingDist = ['packages/ui', 'packages/center-graphic'].some(dir => {
const workspace = JSON.parse(readFileSync(`${dir}/package.json`, 'utf8'));
return Object.values(workspace.exports).some(value => {
const entry = typeof value === 'string' ? value : value.import;
return entry && !existsSync(`${dir}/${entry}`);
});
});
if (missingDist) await completed(run('npm.cmd run build:packages'));
// Exact port prevents interactive port selection, including a startup race.
const server = run('npm.cmd run storybook -- --exact-port --ci');
let stopped = false;
const exit = completed(server).finally(() => { stopped = true; });
// Attach a handler immediately while readiness polling is in progress.
exit.catch(() => {});
const stop = () => completed(run(`taskkill /pid ${server.pid} /t /f`, { stdio: 'ignore' })).catch(() => {});
process.once('SIGINT', async () => { await stop(); process.exit(0); });
process.once('SIGTERM', async () => { await stop(); process.exit(0); });
try {
const deadline = Date.now() + 180000;
while (!stopped && Date.now() < deadline) {
if (await ready()) { await openBrowser(); await exit; break; }
await new Promise(resolve => setTimeout(resolve, 500));
}
if (stopped) await exit;
else throw new Error('Storybook readiness timed out after 3 minutes.');
} catch (error) { await stop(); throw error; }
}