@rip-lang/server 1.1.7 → 1.1.8
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.
- package/package.json +1 -1
- package/server.rip +58 -20
package/package.json
CHANGED
package/server.rip
CHANGED
|
@@ -485,8 +485,8 @@ class Manager
|
|
|
485
485
|
@nextWorkerId = -1
|
|
486
486
|
@retiringIds = new Set()
|
|
487
487
|
@currentVersion = 1
|
|
488
|
-
@
|
|
489
|
-
@
|
|
488
|
+
@server = null
|
|
489
|
+
@appWatchers = new Map()
|
|
490
490
|
|
|
491
491
|
process.on 'SIGTERM', => @shutdown!
|
|
492
492
|
process.on 'SIGINT', => @shutdown!
|
|
@@ -534,13 +534,6 @@ class Manager
|
|
|
534
534
|
utimesSync(entryFile, now, now)
|
|
535
535
|
catch
|
|
536
536
|
null
|
|
537
|
-
# Debounced SSE broadcast to connected clients
|
|
538
|
-
if @onFileChange
|
|
539
|
-
clearTimeout(@_broadcastTimer) if @_broadcastTimer
|
|
540
|
-
@_broadcastTimer = setTimeout =>
|
|
541
|
-
@_broadcastTimer = null
|
|
542
|
-
@onFileChange()
|
|
543
|
-
, debounceMs
|
|
544
537
|
catch e
|
|
545
538
|
console.warn "rip-server: directory watch failed: #{e.message}"
|
|
546
539
|
|
|
@@ -550,6 +543,25 @@ class Manager
|
|
|
550
543
|
try unlinkSync(w.socketPath) catch then null
|
|
551
544
|
@workers = []
|
|
552
545
|
|
|
546
|
+
watchDirs: (prefix, dirs) ->
|
|
547
|
+
return if @appWatchers.has(prefix)
|
|
548
|
+
timer = null
|
|
549
|
+
watchers = []
|
|
550
|
+
broadcast = =>
|
|
551
|
+
clearTimeout(timer) if timer
|
|
552
|
+
timer = setTimeout =>
|
|
553
|
+
timer = null
|
|
554
|
+
@server?.broadcastChange(prefix)
|
|
555
|
+
, 250
|
|
556
|
+
for dir in dirs
|
|
557
|
+
try
|
|
558
|
+
w = watch dir, { recursive: true }, (event, filename) ->
|
|
559
|
+
broadcast() if filename?.endsWith('.rip')
|
|
560
|
+
watchers.push(w)
|
|
561
|
+
catch e
|
|
562
|
+
console.warn "rip-server: watch failed for #{dir}: #{e.message}"
|
|
563
|
+
@appWatchers.set prefix, { watchers, timer }
|
|
564
|
+
|
|
553
565
|
spawnWorker: (version) ->
|
|
554
566
|
workerId = ++@nextWorkerId
|
|
555
567
|
socketPath = getWorkerSocketPath(@flags.socketPrefix, workerId)
|
|
@@ -683,7 +695,8 @@ class Server
|
|
|
683
695
|
@httpsActive = false
|
|
684
696
|
@hostRegistry = new Set(['localhost', '127.0.0.1', 'rip.local'])
|
|
685
697
|
@mdnsProcesses = new Map()
|
|
686
|
-
@
|
|
698
|
+
@watchGroups = new Map()
|
|
699
|
+
@manager = null
|
|
687
700
|
try
|
|
688
701
|
pkg = JSON.parse(readFileSync(import.meta.dir + '/package.json', 'utf8'))
|
|
689
702
|
@serverVersion = pkg.version
|
|
@@ -773,7 +786,12 @@ class Server
|
|
|
773
786
|
return new Response Bun.file(import.meta.dir + '/server.html')
|
|
774
787
|
|
|
775
788
|
return @status() if url.pathname is '/status'
|
|
776
|
-
|
|
789
|
+
|
|
790
|
+
# SSE hot-reload: intercept /{prefix}/watch for registered watch groups
|
|
791
|
+
path = url.pathname
|
|
792
|
+
if path.endsWith('/watch')
|
|
793
|
+
watchPrefix = path.slice(0, -6) # strip '/watch'
|
|
794
|
+
return @handleWatch(watchPrefix) if @watchGroups.has(watchPrefix)
|
|
777
795
|
|
|
778
796
|
if url.pathname is '/server'
|
|
779
797
|
headers = new Headers({ 'content-type': 'text/plain' })
|
|
@@ -818,31 +836,39 @@ class Server
|
|
|
818
836
|
@maybeAddSecurityHeaders(headers)
|
|
819
837
|
new Response(body, { headers })
|
|
820
838
|
|
|
821
|
-
|
|
839
|
+
registerWatch: (prefix) ->
|
|
840
|
+
return if @watchGroups.has(prefix)
|
|
841
|
+
@watchGroups.set prefix, { sseClients: new Set() }
|
|
842
|
+
|
|
843
|
+
handleWatch: (prefix) ->
|
|
844
|
+
group = @watchGroups.get(prefix)
|
|
845
|
+
return new Response('not-found', { status: 404 }) unless group
|
|
822
846
|
encoder = new TextEncoder()
|
|
823
847
|
client = null
|
|
824
848
|
new Response new ReadableStream(
|
|
825
|
-
start: (controller)
|
|
849
|
+
start: (controller) ->
|
|
826
850
|
send = (event) ->
|
|
827
851
|
try controller.enqueue encoder.encode("event: #{event}\n\n")
|
|
828
852
|
catch then null
|
|
829
853
|
client = { send }
|
|
830
|
-
|
|
854
|
+
group.sseClients.add(client)
|
|
831
855
|
send('connected')
|
|
832
|
-
cancel:
|
|
833
|
-
|
|
856
|
+
cancel: ->
|
|
857
|
+
group.sseClients.delete(client) if client
|
|
834
858
|
),
|
|
835
859
|
headers:
|
|
836
860
|
'Content-Type': 'text/event-stream'
|
|
837
861
|
'Cache-Control': 'no-cache'
|
|
838
862
|
'Connection': 'keep-alive'
|
|
839
863
|
|
|
840
|
-
broadcastChange: ->
|
|
864
|
+
broadcastChange: (prefix) ->
|
|
865
|
+
group = @watchGroups.get(prefix)
|
|
866
|
+
return unless group
|
|
841
867
|
dead = []
|
|
842
|
-
for client as
|
|
868
|
+
for client as group.sseClients
|
|
843
869
|
try client.send('reload')
|
|
844
870
|
catch then dead.push(client)
|
|
845
|
-
|
|
871
|
+
group.sseClients.delete(c) for c in dead
|
|
846
872
|
|
|
847
873
|
getNextAvailableSocket: ->
|
|
848
874
|
while @availableWorkers.length > 0
|
|
@@ -979,6 +1005,17 @@ class Server
|
|
|
979
1005
|
null
|
|
980
1006
|
return new Response(JSON.stringify({ ok: false }), { status: 400, headers: { 'content-type': 'application/json' } })
|
|
981
1007
|
|
|
1008
|
+
if req.method is 'POST' and url.pathname is '/watch'
|
|
1009
|
+
try
|
|
1010
|
+
j = req.json!
|
|
1011
|
+
if j?.op is 'watch' and typeof j.prefix is 'string' and Array.isArray(j.dirs)
|
|
1012
|
+
@registerWatch(j.prefix)
|
|
1013
|
+
@manager?.watchDirs(j.prefix, j.dirs) if j.dirs.length > 0
|
|
1014
|
+
return new Response(JSON.stringify({ ok: true }), { headers: { 'content-type': 'application/json' } })
|
|
1015
|
+
catch
|
|
1016
|
+
null
|
|
1017
|
+
return new Response(JSON.stringify({ ok: false }), { status: 400, headers: { 'content-type': 'application/json' } })
|
|
1018
|
+
|
|
982
1019
|
if url.pathname is '/registry' and req.method is 'GET'
|
|
983
1020
|
return new Response(JSON.stringify({ ok: true, hosts: Array.from(@hostRegistry.values()) }), { headers: { 'content-type': 'application/json' } })
|
|
984
1021
|
|
|
@@ -1214,7 +1251,8 @@ main = ->
|
|
|
1214
1251
|
|
|
1215
1252
|
svr = new Server(flags)
|
|
1216
1253
|
mgr = new Manager(flags)
|
|
1217
|
-
|
|
1254
|
+
svr.manager = mgr
|
|
1255
|
+
mgr.server = svr
|
|
1218
1256
|
|
|
1219
1257
|
cleanup = ->
|
|
1220
1258
|
console.log 'rip-server: shutting down...'
|