mirror of
https://github.com/geoffsee/open-gsio.git
synced 2025-09-08 22:56:46 +00:00
* Introduced BevyScene
React component in landing-component
for rendering a 3D cockpit visualization.
* Included WebAssembly asset `yachtpit.js` for cockpit functionality. * Added Bevy MIT license file. * Implemented a service worker to cache assets locally instead of fetching them remotely. * Added collapsible functionality to **Tweakbox** and included the `@chakra-ui/icons` dependency. * Applied the `hidden` prop to the Tweakbox Heading for better accessibility. * Refactored **Particles** component for improved performance, clarity, and maintainability. * Introduced helper functions for particle creation and count management. * Added responsive resizing with particle repositioning. * Optimized animation updates, including velocity adjustments for speed changes. * Ensured canvas size and particle state are cleanly managed on component unmount.
This commit is contained in:

committed by
Geoff Seemueller

parent
858282929c
commit
0ff8b5c03e
164
packages/client/scripts/generate-bevy-bundle.js
Normal file
164
packages/client/scripts/generate-bevy-bundle.js
Normal file
@@ -0,0 +1,164 @@
|
||||
import { execSync } from 'node:child_process';
|
||||
import {
|
||||
existsSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
writeFileSync,
|
||||
renameSync,
|
||||
rmSync,
|
||||
cpSync,
|
||||
} from 'node:fs';
|
||||
import { resolve, dirname, join, basename } from 'node:path';
|
||||
|
||||
import { Logger } from 'tslog';
|
||||
const logger = new Logger({
|
||||
stdio: 'inherit',
|
||||
prettyLogTimeZone: 'local',
|
||||
type: 'pretty',
|
||||
stylePrettyLogs: true,
|
||||
prefix: ['\n'],
|
||||
overwrite: true,
|
||||
});
|
||||
|
||||
function main() {
|
||||
bundleCrate();
|
||||
cleanup();
|
||||
logger.info('🎉 yachtpit built successfully');
|
||||
}
|
||||
|
||||
const getRepoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim();
|
||||
const repoRoot = resolve(getRepoRoot);
|
||||
const publicDir = resolve(repoRoot, 'packages/client/public');
|
||||
const indexHtml = resolve(publicDir, 'index.html');
|
||||
|
||||
function bundleCrate() {
|
||||
// ───────────── Build yachtpit project ───────────────────────────────────
|
||||
logger.info('🔨 Building yachtpit...');
|
||||
|
||||
logger.info(`📁 Repository root: ${repoRoot}`);
|
||||
|
||||
// Check if submodules need to be initialized
|
||||
const yachtpitPath = resolve(repoRoot, 'crates/yachtpit');
|
||||
logger.info(`📁 Yachtpit path: ${yachtpitPath}`);
|
||||
|
||||
if (!existsSync(yachtpitPath)) {
|
||||
logger.info('📦 Initializing submodules...');
|
||||
execSync('git submodule update --init --remote', { stdio: 'inherit' });
|
||||
} else {
|
||||
logger.info(`✅ Submodules already initialized at: ${yachtpitPath}`);
|
||||
}
|
||||
|
||||
// Build the yachtpit project
|
||||
const buildCwd = resolve(repoRoot, 'crates/yachtpit');
|
||||
logger.info(`🔨 Building in directory: ${buildCwd}`);
|
||||
|
||||
try {
|
||||
execSync('trunk build --release', {
|
||||
cwd: buildCwd,
|
||||
});
|
||||
logger.info('✅ Yachtpit built');
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to build yachtpit:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// ───────────── Copy assets to public directory ──────────────────────────
|
||||
const yachtpitDistDir = join(yachtpitPath, 'dist');
|
||||
|
||||
logger.info(`📋 Copying assets to public directory...`);
|
||||
|
||||
// Remove existing yachtpit assets from public directory
|
||||
const skipRemoveOldAssets = false;
|
||||
|
||||
if (!skipRemoveOldAssets) {
|
||||
const existingAssets = readdirSync(publicDir).filter(
|
||||
file => file.startsWith('yachtpit') && (file.endsWith('.js') || file.endsWith('.wasm')),
|
||||
);
|
||||
|
||||
existingAssets.forEach(asset => {
|
||||
const assetPath = join(publicDir, asset);
|
||||
rmSync(assetPath, { force: true });
|
||||
logger.info(`🗑️ Removed old asset: ${assetPath}`);
|
||||
});
|
||||
} else {
|
||||
logger.warn('SKIPPING REMOVING OLD ASSETS');
|
||||
}
|
||||
|
||||
// Copy new assets from yachtpit/dist to public directory
|
||||
if (existsSync(yachtpitDistDir)) {
|
||||
logger.info(`📍Located yachtpit build: ${yachtpitDistDir}`);
|
||||
try {
|
||||
cpSync(yachtpitDistDir, publicDir, {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
logger.info(`✅ Assets copied from ${yachtpitDistDir} to ${publicDir}`);
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to copy assets:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
console.error(`❌ Yachtpit dist directory not found at: ${yachtpitDistDir}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// ───────────── locate targets ───────────────────────────────────────────
|
||||
const dstPath = join(publicDir, 'yachtpit.html');
|
||||
|
||||
// Regexes for the hashed filenames produced by most bundlers
|
||||
const JS_RE = /^yachtpit-[\da-f]{16}\.js$/i;
|
||||
const WASM_RE = /^yachtpit-[\da-f]{16}_bg\.wasm$/i;
|
||||
|
||||
// Always perform renaming of bundle files
|
||||
const files = readdirSync(publicDir);
|
||||
|
||||
// helper that doesn't explode if the target file is already present
|
||||
const safeRename = (from, to) => {
|
||||
if (!existsSync(from)) return;
|
||||
if (existsSync(to)) {
|
||||
logger.info(`ℹ️ ${to} already exists – removing and replacing.`);
|
||||
rmSync(to, { force: true });
|
||||
}
|
||||
renameSync(from, to);
|
||||
logger.info(`📝 Renamed: ${basename(from)} → ${basename(to)}`);
|
||||
};
|
||||
|
||||
files.forEach(f => {
|
||||
const fullPath = join(publicDir, f);
|
||||
if (JS_RE.test(f)) safeRename(fullPath, join(publicDir, 'yachtpit.js'));
|
||||
if (WASM_RE.test(f)) safeRename(fullPath, join(publicDir, 'yachtpit_bg.wasm'));
|
||||
});
|
||||
|
||||
// ───────────── patch markup inside HTML ─────────────────────────────────
|
||||
if (existsSync(indexHtml)) {
|
||||
logger.info(`📝 Patching HTML file: ${indexHtml}`);
|
||||
let html = readFileSync(indexHtml, 'utf8');
|
||||
|
||||
html = html
|
||||
.replace(/yachtpit-[\da-f]{16}\.js/gi, 'yachtpit.js')
|
||||
.replace(/yachtpit-[\da-f]{16}_bg\.wasm/gi, 'yachtpit_bg.wasm');
|
||||
|
||||
writeFileSync(indexHtml, html, 'utf8');
|
||||
|
||||
// ───────────── rename HTML entrypoint ─────────────────────────────────
|
||||
if (basename(indexHtml) !== 'yachtpit.html') {
|
||||
logger.info(`📝 Renaming HTML file: ${indexHtml} → ${dstPath}`);
|
||||
// Remove existing yachtpit.html if it exists
|
||||
if (existsSync(dstPath)) {
|
||||
rmSync(dstPath, { force: true });
|
||||
}
|
||||
renameSync(indexHtml, dstPath);
|
||||
}
|
||||
} else {
|
||||
logger.info(`⚠️ ${indexHtml} not found – skipping HTML processing.`);
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
logger.info('Running cleanup...');
|
||||
rmSync(indexHtml, { force: true });
|
||||
const creditsDir = resolve(`${repoRoot}/packages/client/public`, 'credits');
|
||||
rmSync(creditsDir, { force: true, recursive: true });
|
||||
}
|
||||
|
||||
main();
|
Reference in New Issue
Block a user