@getvision/server 0.2.2 → 0.2.4
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/CHANGELOG.md +13 -0
- package/package.json +2 -2
- package/src/vision-app.ts +60 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @getvision/server
|
|
2
2
|
|
|
3
|
+
## 0.2.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- b0ab5ad: Run in Bun environment if Bun was detected
|
|
8
|
+
|
|
9
|
+
## 0.2.3
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [d227b1d]
|
|
14
|
+
- @getvision/core@0.0.5
|
|
15
|
+
|
|
3
16
|
## 0.2.2
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getvision/server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vision Server - Meta-framework with built-in observability, pub/sub, and type-safe APIs",
|
|
6
6
|
"exports": {
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@getvision/core": "0.0.
|
|
16
|
+
"@getvision/core": "0.0.5",
|
|
17
17
|
"@hono/node-server": "^1.19.6",
|
|
18
18
|
"bullmq": "^5.62.0",
|
|
19
19
|
"hono-rate-limiter": "^0.4.2",
|
package/src/vision-app.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { VisionCore } from '@getvision/core'
|
|
|
4
4
|
import type { RouteMetadata } from '@getvision/core'
|
|
5
5
|
import { AsyncLocalStorage } from 'async_hooks'
|
|
6
6
|
import { existsSync } from 'fs'
|
|
7
|
-
import { spawn, type ChildProcess } from 'child_process'
|
|
7
|
+
import { spawn, spawnSync, type ChildProcess } from 'child_process'
|
|
8
8
|
import { ServiceBuilder } from './service'
|
|
9
9
|
import { EventBus } from './event-bus'
|
|
10
10
|
import { eventRegistry } from './event-registry'
|
|
@@ -106,6 +106,8 @@ export class Vision<
|
|
|
106
106
|
private config: VisionConfig
|
|
107
107
|
private serviceBuilders: ServiceBuilder<any, E>[] = []
|
|
108
108
|
private fileBasedRoutes: RouteMetadata[] = []
|
|
109
|
+
private bunServer?: any
|
|
110
|
+
private shuttingDown = false
|
|
109
111
|
|
|
110
112
|
constructor(config?: VisionConfig) {
|
|
111
113
|
super()
|
|
@@ -599,18 +601,53 @@ export class Vision<
|
|
|
599
601
|
console.log(`🚀 Starting ${this.config.service.name}...`)
|
|
600
602
|
console.log(`📡 API Server: http://localhost:${port}`)
|
|
601
603
|
|
|
602
|
-
// Setup cleanup on exit
|
|
604
|
+
// Setup cleanup on exit (ensure it runs once)
|
|
603
605
|
const cleanup = async () => {
|
|
606
|
+
if (this.shuttingDown) return
|
|
607
|
+
this.shuttingDown = true
|
|
604
608
|
console.log('🛑 Shutting down...')
|
|
605
|
-
|
|
609
|
+
try {
|
|
610
|
+
if (this.bunServer && typeof this.bunServer.stop === 'function') {
|
|
611
|
+
try { this.bunServer.stop() } catch {}
|
|
612
|
+
}
|
|
613
|
+
try { if ((globalThis as any).__vision_bun_server === this.bunServer) (globalThis as any).__vision_bun_server = undefined } catch {}
|
|
614
|
+
} catch {}
|
|
615
|
+
try { stopDrizzleStudio() } catch {}
|
|
616
|
+
try { await this.eventBus.close() } catch {}
|
|
606
617
|
}
|
|
607
618
|
|
|
608
|
-
|
|
609
|
-
|
|
619
|
+
const wrappedCleanup = async () => {
|
|
620
|
+
await cleanup()
|
|
621
|
+
try { process.exit(0) } catch {}
|
|
622
|
+
}
|
|
623
|
+
process.once('SIGINT', wrappedCleanup)
|
|
624
|
+
process.once('SIGTERM', wrappedCleanup)
|
|
625
|
+
try { process.once('SIGQUIT', wrappedCleanup) } catch {}
|
|
610
626
|
|
|
611
|
-
//
|
|
612
|
-
if (typeof process !== 'undefined' && process.versions
|
|
627
|
+
// Prefer Bun if available, then Node.js; otherwise instruct the user to serve manually
|
|
628
|
+
if (typeof process !== 'undefined' && process.versions?.bun) {
|
|
629
|
+
const BunServe = (globalThis as any).Bun?.serve
|
|
630
|
+
if (typeof BunServe === 'function') {
|
|
631
|
+
console.log(`Bun detected`)
|
|
632
|
+
try {
|
|
633
|
+
const existing = (globalThis as any).__vision_bun_server
|
|
634
|
+
if (existing && typeof existing.stop === 'function') {
|
|
635
|
+
try { existing.stop() } catch {}
|
|
636
|
+
}
|
|
637
|
+
} catch {}
|
|
638
|
+
this.bunServer = BunServe({
|
|
639
|
+
fetch: this.fetch.bind(this),
|
|
640
|
+
port,
|
|
641
|
+
hostname: options?.hostname
|
|
642
|
+
})
|
|
643
|
+
try { (globalThis as any).__vision_bun_server = this.bunServer } catch {}
|
|
644
|
+
} else {
|
|
645
|
+
console.warn('Bun detected but Bun.serve is unavailable')
|
|
646
|
+
return this
|
|
647
|
+
}
|
|
648
|
+
} else if (typeof process !== 'undefined' && process.versions?.node) {
|
|
613
649
|
const { serve } = await import('@hono/node-server')
|
|
650
|
+
console.log(`Node.js detected`)
|
|
614
651
|
serve({
|
|
615
652
|
fetch: this.fetch.bind(this),
|
|
616
653
|
port,
|
|
@@ -671,7 +708,22 @@ function startDrizzleStudio(port: number): boolean {
|
|
|
671
708
|
return false
|
|
672
709
|
}
|
|
673
710
|
|
|
674
|
-
|
|
711
|
+
// If Drizzle Studio is already listening on this port, skip spawning but report available
|
|
712
|
+
try {
|
|
713
|
+
if (process.platform === 'win32') {
|
|
714
|
+
const res = spawnSync('powershell', ['-NoProfile', '-Command', `netstat -ano | Select-String -Pattern "LISTENING\\s+.*:${port}\\s"`], { encoding: 'utf-8' })
|
|
715
|
+
if ((res.stdout || '').trim().length > 0) {
|
|
716
|
+
console.log(`⚠️ Drizzle Studio port ${port} already in use; assuming it is running. Skipping auto-start.`)
|
|
717
|
+
return true
|
|
718
|
+
}
|
|
719
|
+
} else {
|
|
720
|
+
const res = spawnSync('lsof', ['-i', `tcp:${port}`, '-sTCP:LISTEN'], { encoding: 'utf-8' })
|
|
721
|
+
if ((res.stdout || '').trim().length > 0) {
|
|
722
|
+
console.log(`⚠️ Drizzle Studio port ${port} already in use; assuming it is running. Skipping auto-start.`)
|
|
723
|
+
return true
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
} catch {}
|
|
675
727
|
|
|
676
728
|
try {
|
|
677
729
|
drizzleStudioProcess = spawn('npx', ['drizzle-kit', 'studio', '--port', String(port), '--host', '0.0.0.0'], {
|