@epic-web/workshop-app 5.24.2 → 5.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/epicshop.js +59 -9
  2. package/package.json +4 -3
package/bin/epicshop.js CHANGED
@@ -4,10 +4,13 @@ import { spawn } from 'child_process'
4
4
  import crypto from 'crypto'
5
5
  import fs from 'fs'
6
6
  import http from 'http'
7
+ import os from 'os'
7
8
  import path from 'path'
8
9
  import { fileURLToPath } from 'url'
10
+ import chalk from 'chalk'
9
11
  import closeWithGrace from 'close-with-grace'
10
12
  import getPort from 'get-port'
13
+ import open from 'open'
11
14
 
12
15
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
13
16
  const isPublished = !fs.existsSync(path.join(__dirname, '..', 'app'))
@@ -60,9 +63,13 @@ async function start() {
60
63
  let server = null
61
64
  let child = null
62
65
  let restarting = false
66
+ let childPort = null
63
67
  let childPortPromiseResolve = null
64
- const childPort = new Promise((resolve) => {
68
+ const childPortPromise = new Promise((resolve) => {
65
69
  childPortPromiseResolve = resolve
70
+ }).then((port) => {
71
+ childPort = port
72
+ return port
66
73
  })
67
74
 
68
75
  function parsePortFromLine(line) {
@@ -74,7 +81,7 @@ async function start() {
74
81
  }
75
82
 
76
83
  async function waitForChildReady() {
77
- const port = await childPort
84
+ const port = await childPortPromise
78
85
  const url = `http://localhost:${port}/`
79
86
  const maxAttempts = 40 // 20s max (500ms interval)
80
87
  for (let i = 0; i < maxAttempts; i++) {
@@ -187,15 +194,13 @@ async function start() {
187
194
  if (child.stdout) {
188
195
  child.stdout.on('data', (data) => {
189
196
  process.stdout.write(data)
190
-
191
- if (childPortPromiseResolve) {
197
+ if (!childPort) {
192
198
  const str = data.toString('utf8')
193
199
  const lines = str.split(/\r?\n/)
194
200
  for (const line of lines) {
195
201
  const port = parsePortFromLine(line)
196
- if (port && childPortPromiseResolve) {
197
- childPortPromiseResolve(port)
198
- childPortPromiseResolve = null
202
+ if (port) {
203
+ childPortPromiseResolve?.(port)
199
204
  }
200
205
  }
201
206
  }
@@ -211,10 +216,14 @@ async function start() {
211
216
  })
212
217
  }
213
218
 
219
+ console.log(
220
+ `🐨 Welcome to the workshop, ${chalk.bold.italic(os.userInfo().username)}!`,
221
+ )
222
+
214
223
  spawnChild()
215
224
 
216
- // Listen for 'u' key to update and restart
217
- if (process.stdin.isTTY) {
225
+ if (process.stdin.isTTY && !isDeployed) {
226
+ printSupportedKeys()
218
227
  process.stdin.setRawMode(true)
219
228
  process.stdin.resume()
220
229
  process.stdin.setEncoding('utf8')
@@ -224,6 +233,38 @@ async function start() {
224
233
  '\nšŸ”„ Update requested from terminal. Running update and restarting app process...',
225
234
  )
226
235
  await doUpdateAndRestart()
236
+ } else if (key === 'o') {
237
+ if (childPort) {
238
+ console.log(
239
+ chalk.blue(
240
+ `\n🌐 Opening browser to http://localhost:${childPort} ...`,
241
+ ),
242
+ )
243
+ await open(`http://localhost:${childPort}`)
244
+ } else {
245
+ console.log(chalk.red('Local server URL not available yet.'))
246
+ }
247
+ } else if (key === 'q') {
248
+ console.log(chalk.yellow('\nšŸ‘‹ Exiting...'))
249
+ await cleanupBeforeExit()
250
+ process.exit(0)
251
+ } else if (key === 'r') {
252
+ console.log(chalk.magenta('\nšŸ”„ Restarting app process...'))
253
+ restarting = true
254
+ await killChild(child)
255
+ restarting = false
256
+ spawnChild()
257
+ } else if (key === 'k') {
258
+ const messages = [
259
+ chalk.bgCyan.black('🐨 Kody says: You are koalafied for greatness!'),
260
+ chalk.bgGreen.black('🐨 Kody says: Keep going, you are pawsome!'),
261
+ chalk.bgMagenta.white('🐨 Kody says: Eucalyptus up and code on!'),
262
+ chalk.bgYellow.black('🐨 Kody says: You can do it, fur real!'),
263
+ chalk.bgBlue.white('🐨 Kody says: Stay curious, stay cuddly!'),
264
+ chalk.bgRed.white("🐨 Kody says: Don't leaf your dreams behind!"),
265
+ ]
266
+ const msg = messages[Math.floor(Math.random() * messages.length)]
267
+ console.log('\n' + msg + '\n')
227
268
  } else if (key === '\u0003') {
228
269
  // Ctrl+C
229
270
  await cleanupBeforeExit()
@@ -251,3 +292,12 @@ async function killChild(child) {
251
292
  child.kill()
252
293
  })
253
294
  }
295
+
296
+ function printSupportedKeys() {
297
+ console.log(chalk.bold.cyan('\nSupported keys:'))
298
+ console.log(` ${chalk.blue('o')} - open browser`)
299
+ console.log(` ${chalk.green('u')} - update repo`)
300
+ console.log(` ${chalk.magenta('r')} - restart`)
301
+ console.log(` ${chalk.cyan('k')} - Kody kudos 🐨`)
302
+ console.log(` ${chalk.gray('q')} (or ${chalk.gray('Ctrl+C')}) - exit`)
303
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epic-web/workshop-app",
3
- "version": "5.24.2",
3
+ "version": "5.26.0",
4
4
  "sideEffects": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -44,8 +44,8 @@
44
44
  "@epic-web/invariant": "^1.0.0",
45
45
  "@epic-web/remember": "^1.1.0",
46
46
  "@epic-web/restore-scroll": "^1.1.1",
47
- "@epic-web/workshop-presence": "5.24.2",
48
- "@epic-web/workshop-utils": "5.24.2",
47
+ "@epic-web/workshop-presence": "5.26.0",
48
+ "@epic-web/workshop-utils": "5.26.0",
49
49
  "@mdx-js/mdx": "^3.0.1",
50
50
  "@mux/mux-player-react": "^3.0.0",
51
51
  "@nasa-gcn/remix-seo": "^2.0.1",
@@ -92,6 +92,7 @@
92
92
  "mime-types": "^2.1.35",
93
93
  "morgan": "^1.10.0",
94
94
  "msw": "^2.4.9",
95
+ "open": "^8.4.2",
95
96
  "openid-client": "^6.1.7",
96
97
  "p-queue": "^8.0.1",
97
98
  "partysocket": "^1.0.2",