Skip to content

Commit 55f0c02

Browse files
authored
fix: start tamagotchi (#630)
1 parent 548130d commit 55f0c02

File tree

2 files changed

+126
-1
lines changed

2 files changed

+126
-1
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#!/usr/bin/env tsx
2+
/**
3+
* Development script to start both the WebSocket server and Tamagotchi app
4+
* This ensures the server-runtime is running before starting the app
5+
*/
6+
7+
import type { Buffer } from 'node:buffer'
8+
9+
import process from 'node:process'
10+
11+
import { spawn } from 'node:child_process'
12+
13+
const isWindows = process.platform === 'win32'
14+
15+
console.log('🚀 Starting AIRI WebSocket server and Tamagotchi app...\n')
16+
17+
// Start the WebSocket server in the background
18+
console.log('📡 Starting WebSocket server on port 6121...')
19+
const serverProcess = spawn(
20+
'pnpm',
21+
['-F', '@proj-airi/server-runtime', 'dev'],
22+
{
23+
stdio: ['pipe', 'pipe', 'pipe'], // Change from 'inherit' to capture output
24+
shell: isWindows,
25+
},
26+
)
27+
28+
// Wait for the server to be ready by listening for a ready message
29+
console.log('⏳ Waiting for server to initialize...\n')
30+
const serverReady = new Promise<void>((resolve, reject) => {
31+
// Listen typically outputs a URL when ready, looking for patterns like:
32+
// "Listening on http://localhost:6121" or similar
33+
const readyPatterns = [
34+
/listening.*:6121/i,
35+
/ready.*:6121/i,
36+
/localhost:6121/i,
37+
/http:\/\/localhost:6121/i,
38+
]
39+
40+
const timeout = setTimeout(() => {
41+
console.log('⚠️ Server ready timeout reached, continuing anyway...')
42+
resolve() // Resolve even if we don't see the message to avoid hanging
43+
}, 10000) // 10 second timeout
44+
45+
// Handle errors from the server process
46+
serverProcess.on('error', (error) => {
47+
console.error('Failed to start server:', error)
48+
clearTimeout(timeout)
49+
reject(error)
50+
})
51+
52+
const checkOutput = (data: Buffer) => {
53+
const output = data.toString()
54+
console.log(output) // Still output to console for visibility
55+
56+
if (readyPatterns.some(pattern => pattern.test(output))) {
57+
clearTimeout(timeout)
58+
resolve()
59+
}
60+
}
61+
62+
serverProcess.stdout?.on('data', checkOutput)
63+
serverProcess.stderr?.on('data', checkOutput)
64+
})
65+
66+
await serverReady
67+
68+
// Start the Tamagotchi app
69+
console.log('🎮 Starting Tamagotchi app...\n')
70+
const tamagotchiProcess = spawn(
71+
'pnpm',
72+
['-F', '@proj-airi/stage-tamagotchi', 'app:dev'],
73+
{
74+
stdio: 'inherit',
75+
shell: isWindows,
76+
},
77+
)
78+
79+
let isCleaningUp = false
80+
81+
// Handle cleanup on exit
82+
function cleanup() {
83+
if (isCleaningUp)
84+
return
85+
isCleaningUp = true
86+
console.log('\n🛑 Shutting down...')
87+
try {
88+
if (serverProcess && !serverProcess.killed) {
89+
serverProcess.kill()
90+
}
91+
}
92+
catch (error) {
93+
console.error('Error killing server process:', error)
94+
}
95+
try {
96+
if (tamagotchiProcess && !tamagotchiProcess.killed) {
97+
tamagotchiProcess.kill()
98+
}
99+
}
100+
catch (error) {
101+
console.error('Error killing tamagotchi process:', error)
102+
}
103+
}
104+
105+
process.on('SIGINT', cleanup)
106+
process.on('SIGTERM', cleanup)
107+
108+
// Wait for processes
109+
const serverExit = new Promise(resolve => serverProcess.on('exit', code => resolve({ name: 'Server', code })))
110+
const tamagotchiExit = new Promise(resolve => tamagotchiProcess.on('exit', code => resolve({ name: 'Tamagotchi', code })))
111+
112+
const firstToExit = await Promise.race([serverExit, tamagotchiExit])
113+
114+
console.log(`${firstToExit.name} process exited with code ${firstToExit.code}, shutting down...`)
115+
cleanup()
116+
117+
// Wait for both processes to terminate before exiting the script.
118+
await Promise.all([serverExit, tamagotchiExit])
119+
120+
console.log('All child processes have terminated.')
121+
process.exit(firstToExit.code ?? 0)

apps/stage-tamagotchi/src/main/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ function createWindow(): void {
6161
})
6262

6363
mainWindow.setAlwaysOnTop(true)
64-
mainWindow.setWindowButtonVisibility(false)
64+
if (isMacOS) {
65+
mainWindow.setWindowButtonVisibility(false)
66+
}
6567
mainWindow.on('ready-to-show', () => mainWindow!.show())
6668
mainWindow.webContents.setWindowOpenHandler((details) => {
6769
shell.openExternal(details.url)
@@ -125,6 +127,8 @@ app.whenReady().then(() => {
125127
app.on('browser-window-created', (_, window) => optimizer.watchWindowShortcuts(window))
126128

127129
createWindow()
130+
}).catch((err) => {
131+
console.error('Error during app initialization:', err)
128132
})
129133

130134
// Quit when all windows are closed, except on macOS. There, it's common

0 commit comments

Comments
 (0)