@rip-lang/server 1.3.18 → 1.3.20

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/package.json +2 -2
  2. package/server.rip +37 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rip-lang/server",
3
- "version": "1.3.18",
3
+ "version": "1.3.20",
4
4
  "description": "Pure Rip web framework and application server",
5
5
  "type": "module",
6
6
  "main": "api.rip",
@@ -45,7 +45,7 @@
45
45
  "author": "Steve Shreeve <steve.shreeve@gmail.com>",
46
46
  "license": "MIT",
47
47
  "dependencies": {
48
- "rip-lang": ">=3.13.34"
48
+ "rip-lang": ">=3.13.36"
49
49
  },
50
50
  "files": [
51
51
  "api.rip",
package/server.rip CHANGED
@@ -339,6 +339,7 @@ parseFlags = (argv) ->
339
339
  hsts: has('--hsts')
340
340
  redirectHttp: not has('--no-redirect-http')
341
341
  reload
342
+ quiet: has('--quiet')
342
343
  socketPrefix
343
344
  maxQueue: coerceInt(getKV('--max-queue='), coerceInt(process.env.RIP_MAX_QUEUE, 512))
344
345
  queueTimeoutMs: coerceInt(getKV('--queue-timeout-ms='), coerceInt(process.env.RIP_QUEUE_TIMEOUT_MS, 30000))
@@ -361,6 +362,13 @@ runSetup = ->
361
362
  fn = mod?.setup or mod?.default
362
363
  if typeof fn is 'function'
363
364
  await fn()
365
+ # Signal the Manager that setup is complete
366
+ process.stdout.write '__setup_done__\n'
367
+ # If teardown exported, stay alive until Manager sends SIGTERM
368
+ if typeof mod?.teardown is 'function'
369
+ await new Promise (resolve) ->
370
+ process.once 'SIGTERM', ->
371
+ Promise.resolve(mod.teardown()).finally(resolve)
364
372
  catch e
365
373
  console.error "rip-server: setup failed:", e
366
374
  process.exit(1)
@@ -499,6 +507,7 @@ class Manager
499
507
  @retiringIds = new Set()
500
508
  @currentVersion = 1
501
509
  @server = null
510
+ @setupProc = null
502
511
  @appWatchers = new Map()
503
512
 
504
513
  process.on 'SIGTERM', => @shutdown!
@@ -514,15 +523,32 @@ class Manager
514
523
  RIP_SETUP_MODE: '1'
515
524
  RIP_SETUP_FILE: setupFile
516
525
  proc = Bun.spawn ['rip', import.meta.path],
517
- stdout: 'inherit'
526
+ stdout: 'pipe'
518
527
  stderr: 'inherit'
519
528
  stdin: 'ignore'
520
529
  cwd: process.cwd()
521
530
  env: setupEnv
522
- code = await proc.exited
523
- if code isnt 0
524
- console.error "rip-server: setup exited with code #{code}"
525
- process.exit(1)
531
+
532
+ # Stream stdout to our stdout, watching for the __setup_done__ signal
533
+ setupDone = new Promise (resolve, reject) ->
534
+ buf = ''
535
+ reader = proc.stdout.getReader()
536
+ dec = new TextDecoder()
537
+ readLoop = ->
538
+ { done, value } = await reader.read()
539
+ if done
540
+ code = await proc.exited
541
+ if code isnt 0 then reject new Error "setup exited #{code}" else resolve()
542
+ return
543
+ buf += dec.decode(value)
544
+ lines = buf.split('\n')
545
+ buf = lines.pop()
546
+ for line in lines
547
+ if line is '__setup_done__' then resolve() else process.stdout.write line + '\n'
548
+ readLoop()
549
+ readLoop()
550
+ await setupDone
551
+ @setupProc = proc
526
552
 
527
553
  @workers = []
528
554
  for i in [0...@flags.workers]
@@ -710,6 +736,8 @@ class Manager
710
736
  return if @shuttingDown
711
737
  @shuttingDown = true
712
738
  @stop!
739
+ # Signal the setup process to run teardown (kills rip-db if we launched it)
740
+ @setupProc?.kill('SIGTERM')
713
741
  process.exit(0)
714
742
 
715
743
  getEntryMtime: ->
@@ -1017,7 +1045,7 @@ class Server
1017
1045
 
1018
1046
  port = @flags.httpsPort or @flags.httpPort or 80
1019
1047
  protocol = if @flags.httpsPort then 'https' else 'http'
1020
- console.log "rip-server: #{protocol}://#{@flags.appName}.ripdev.io#{formatPort(protocol, port)}"
1048
+ console.log "rip-server: #{protocol}://#{@flags.appName}.ripdev.io#{formatPort(protocol, port)}" unless @flags.quiet
1021
1049
 
1022
1050
  controlFetch: (req) ->
1023
1051
  url = new URL(req.url)
@@ -1139,7 +1167,7 @@ class Server
1139
1167
  stderr: 'ignore'
1140
1168
 
1141
1169
  @mdnsProcesses.set(host, proc)
1142
- console.log "rip-server: #{protocol}://#{host}#{formatPort(protocol, port)}"
1170
+ console.log "rip-server: #{protocol}://#{host}#{formatPort(protocol, port)}" unless @flags.quiet
1143
1171
  catch e
1144
1172
  console.error "rip-server: failed to advertise #{host} via mDNS:", e.message
1145
1173
 
@@ -1174,6 +1202,7 @@ main = ->
1174
1202
  --static Disable hot reload and file watching
1175
1203
  --env=<mode> Set environment (dev, production)
1176
1204
  --debug Enable debug logging
1205
+ --quiet Suppress URL lines (app prints its own)
1177
1206
 
1178
1207
  Network:
1179
1208
  http HTTP only (no TLS)
@@ -1287,6 +1316,7 @@ main = ->
1287
1316
 
1288
1317
  httpOnly = flags.httpsPort is null
1289
1318
  protocol = if httpOnly then 'http' else 'https'
1319
+ process.env.RIP_HTTP_ONLY = '1' if httpOnly
1290
1320
  port = flags.httpsPort or flags.httpPort or 80
1291
1321
  console.log "rip-server: app=#{flags.appName} workers=#{flags.workers} url=#{protocol}://#{flags.appName}.ripdev.io#{formatPort(protocol, port)}/server"
1292
1322