@getvision/server 0.0.1 → 0.1.0-5d94ff9-develop

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.
@@ -1,2 +1 @@
1
-
2
- $ tsc --noEmit
1
+ $ tsc --noEmit
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getvision/server",
3
- "version": "0.0.1",
3
+ "version": "0.1.0-5d94ff9-develop",
4
4
  "type": "module",
5
5
  "description": "Vision Server - Meta-framework with built-in observability, pub/sub, and type-safe APIs",
6
6
  "exports": {
@@ -16,14 +16,14 @@
16
16
  "@getvision/core": "0.0.1",
17
17
  "@hono/node-server": "^1.19.5",
18
18
  "bullmq": "^5.62.0",
19
- "hono": "^4.10.3",
19
+ "hono": "^4.10.4",
20
20
  "ioredis": "^5.8.2",
21
21
  "zod": "^4.1.11"
22
22
  },
23
23
  "peerDependencies": {},
24
24
  "devDependencies": {
25
- "@repo/eslint-config": "0.0.0",
26
- "@repo/typescript-config": "0.0.0",
25
+ "@repo/eslint-config": "0.0.1",
26
+ "@repo/typescript-config": "0.0.1",
27
27
  "@types/node": "^20.14.9",
28
28
  "typescript": "5.9.3"
29
29
  },
package/src/service.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { Hono, Context, MiddlewareHandler } from 'hono'
1
+ import type { Hono, Context, MiddlewareHandler, Env, Input } from 'hono'
2
2
  import type { z } from 'zod'
3
3
  import { VisionCore, generateZodTemplate } from '@getvision/core'
4
- import type { EndpointConfig, Handler, VisionContext } from './types'
4
+ import type { EndpointConfig, Handler } from './types'
5
5
  import { getVisionContext } from './vision-app'
6
6
  import { eventRegistry } from './event-registry'
7
7
  import type { EventBus } from './event-bus'
@@ -29,11 +29,15 @@ type EventSchemaMap = Record<string, z.ZodSchema<any>>
29
29
  * })
30
30
  * ```
31
31
  */
32
- export class ServiceBuilder<TEvents extends EventSchemaMap = {}> {
32
+ export class ServiceBuilder<
33
+ TEvents extends EventSchemaMap = {},
34
+ E extends Env = Env,
35
+ I extends Input = {}
36
+ > {
33
37
  private endpoints: Map<string, any> = new Map()
34
38
  private eventHandlers: Map<string, any> = new Map()
35
39
  private cronJobs: Map<string, any> = new Map()
36
- private globalMiddleware: MiddlewareHandler[] = []
40
+ private globalMiddleware: MiddlewareHandler<E, string, any, any>[] = []
37
41
  private eventSchemas: EventSchemaMap = {}
38
42
 
39
43
  constructor(
@@ -45,7 +49,7 @@ export class ServiceBuilder<TEvents extends EventSchemaMap = {}> {
45
49
  /**
46
50
  * Add global middleware for all endpoints in this service
47
51
  */
48
- use(...middleware: MiddlewareHandler[]) {
52
+ use(...middleware: MiddlewareHandler<E, string, any, any>[]) {
49
53
  this.globalMiddleware.push(...middleware)
50
54
  return this
51
55
  }
@@ -109,15 +113,23 @@ export class ServiceBuilder<TEvents extends EventSchemaMap = {}> {
109
113
  */
110
114
  endpoint<
111
115
  TInputSchema extends z.ZodType,
112
- TOutputSchema extends z.ZodType
116
+ TOutputSchema extends z.ZodType | undefined,
117
+ PPath extends string
113
118
  >(
114
119
  method: EndpointConfig['method'],
115
- path: string,
120
+ path: PPath,
116
121
  schema: {
117
122
  input: TInputSchema
118
- output: TOutputSchema
123
+ output?: TOutputSchema
119
124
  },
120
- handler: Handler<z.infer<TInputSchema>, z.infer<TOutputSchema>, TEvents>,
125
+ handler: Handler<
126
+ z.infer<TInputSchema>,
127
+ TOutputSchema extends z.ZodType ? z.infer<TOutputSchema> : any,
128
+ TEvents,
129
+ E,
130
+ PPath,
131
+ I
132
+ >,
121
133
  config?: Partial<EndpointConfig>
122
134
  ) {
123
135
  this.endpoints.set(`${method}:${path}`, {
@@ -166,7 +178,7 @@ export class ServiceBuilder<TEvents extends EventSchemaMap = {}> {
166
178
  tags?: string[]
167
179
  handler: (event: T) => Promise<void>
168
180
  }
169
- ): ServiceBuilder<TEvents & { [key in K]: T }> {
181
+ ): ServiceBuilder<TEvents & { [key in K]: T }, E, I> {
170
182
  const { schema, handler, description, icon, tags } = config
171
183
 
172
184
  // Store schema for type inference
@@ -187,7 +199,7 @@ export class ServiceBuilder<TEvents extends EventSchemaMap = {}> {
187
199
  this.eventHandlers.set(eventName, config)
188
200
 
189
201
  // Return typed ServiceBuilder with accumulated events
190
- return this as ServiceBuilder<TEvents & { [key in K]: T }>
202
+ return this as ServiceBuilder<TEvents & { [key in K]: T }, E, I>
191
203
  }
192
204
 
193
205
  /**
@@ -307,7 +319,7 @@ export class ServiceBuilder<TEvents extends EventSchemaMap = {}> {
307
319
  const allMiddleware = [...this.globalMiddleware, ...ep.middleware]
308
320
 
309
321
  // Create handler with middleware chain
310
- const finalHandler = async (c: Context) => {
322
+ const finalHandler = async (c: Context<E, any, I>) => {
311
323
  try {
312
324
  // Add span helper and emit to context
313
325
  const visionCtx = getVisionContext()
@@ -378,11 +390,18 @@ export class ServiceBuilder<TEvents extends EventSchemaMap = {}> {
378
390
 
379
391
  // Execute handler
380
392
  const result = await ep.handler(validated, c as any)
381
-
382
- // Validate output with Zod
383
- const validatedOutput = ep.schema.output.parse(result)
384
-
385
- return c.json(validatedOutput)
393
+
394
+ // If an output schema exists, validate and return JSON
395
+ if (ep.schema.output) {
396
+ const validatedOutput = ep.schema.output.parse(result)
397
+ return c.json(validatedOutput)
398
+ }
399
+
400
+ // No output schema: allow raw Response or JSON
401
+ if (result instanceof Response) {
402
+ return result
403
+ }
404
+ return c.json(result)
386
405
  } catch (error) {
387
406
  if ((error as any).name === 'ZodError') {
388
407
  return c.json({
package/src/types.ts CHANGED
@@ -1,11 +1,10 @@
1
- import type { Context, MiddlewareHandler } from 'hono'
2
- import type { z } from 'zod'
1
+ import type { Context, Env, Input, MiddlewareHandler } from 'hono'
3
2
  import type { VisionCore } from '@getvision/core'
4
3
 
5
4
  /**
6
5
  * Vision context stored in AsyncLocalStorage
7
6
  */
8
- export interface VisionContext {
7
+ export interface VisionContext<E extends Env = any, P extends string = any, I extends Input = {}> extends Context<E, P, I> {
9
8
  vision: VisionCore
10
9
  traceId: string
11
10
  rootSpanId: string
@@ -18,6 +17,7 @@ export interface EndpointConfig {
18
17
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'
19
18
  path: string
20
19
  middleware?: MiddlewareHandler[]
20
+ // TODO: Below not implemented yet features
21
21
  auth?: boolean
22
22
  ratelimit?: { requests: number; window: string }
23
23
  cache?: { ttl: number }
@@ -28,7 +28,12 @@ export interface EndpointConfig {
28
28
  *
29
29
  * Generic TEvents parameter allows type-safe event emission
30
30
  */
31
- export interface ExtendedContext<TEvents extends Record<string, any> = {}> extends Context {
31
+ export interface ExtendedContext<
32
+ TEvents extends Record<string, any> = {},
33
+ E extends Env = any,
34
+ P extends string = any,
35
+ I extends Input = {}
36
+ > extends Context<E, P, I> {
32
37
  span<T>(
33
38
  name: string,
34
39
  attributes?: Record<string, any>,
@@ -68,7 +73,14 @@ export interface ExtendedContext<TEvents extends Record<string, any> = {}> exten
68
73
  /**
69
74
  * Handler type with Zod-validated input and Vision-enhanced context
70
75
  */
71
- export type Handler<TInput = any, TOutput = any, TEvents extends Record<string, any> = {}> = (
76
+ export type Handler<
77
+ TInput = any,
78
+ TOutput = any,
79
+ TEvents extends Record<string, any> = {},
80
+ E extends Env = any,
81
+ P extends string = any,
82
+ I extends Input = {}
83
+ > = (
72
84
  req: TInput,
73
- ctx: ExtendedContext<TEvents>
85
+ ctx: ExtendedContext<TEvents, E, P, I>
74
86
  ) => Promise<TOutput> | TOutput
package/src/vision-app.ts CHANGED
@@ -6,11 +6,16 @@ import { AsyncLocalStorage } from 'async_hooks'
6
6
  import { existsSync } from 'fs'
7
7
  import { spawn, type ChildProcess } from 'child_process'
8
8
  import { ServiceBuilder } from './service'
9
- import type { VisionContext } from './types'
10
9
  import { EventBus } from './event-bus'
11
10
  import { eventRegistry } from './event-registry'
12
11
 
13
- const visionContext = new AsyncLocalStorage<VisionContext>()
12
+ export interface VisionALSContext {
13
+ vision: VisionCore
14
+ traceId: string
15
+ rootSpanId: string
16
+ }
17
+
18
+ const visionContext = new AsyncLocalStorage<VisionALSContext>()
14
19
 
15
20
  /**
16
21
  * Vision Server configuration
@@ -81,7 +86,7 @@ export class Vision<
81
86
  private visionCore: VisionCore
82
87
  private eventBus: EventBus
83
88
  private config: VisionConfig
84
- private serviceBuilders: ServiceBuilder<any>[] = []
89
+ private serviceBuilders: ServiceBuilder<any, E>[] = []
85
90
  private fileBasedRoutes: RouteMetadata[] = []
86
91
 
87
92
  constructor(config?: VisionConfig) {
@@ -253,11 +258,11 @@ export class Vision<
253
258
 
254
259
  // Run request in AsyncLocalStorage context
255
260
  return visionContext.run(
256
- {
257
- vision: this.visionCore,
258
- traceId: trace.id,
259
- rootSpanId: ''
260
- },
261
+ {
262
+ vision: this.visionCore,
263
+ traceId: trace.id,
264
+ rootSpanId: ''
265
+ },
261
266
  async () => {
262
267
  // Start main span
263
268
  const tracer = this.visionCore.getTracer()
@@ -427,11 +432,11 @@ export class Vision<
427
432
  * .on('user/created', handler)
428
433
  * ```
429
434
  */
430
- service<TEvents extends Record<string, any> = {}>(name: string) {
431
- const builder = new ServiceBuilder<TEvents>(name, this.eventBus, this.visionCore)
435
+ service<E2 extends Env = E, TEvents extends Record<string, any> = {}>(name: string) {
436
+ const builder = new ServiceBuilder<TEvents, E2>(name, this.eventBus, this.visionCore)
432
437
 
433
- // Зберігаємо builder для реєстрації в start()
434
- this.serviceBuilders.push(builder)
438
+ // Preserve builder for registration in start()
439
+ this.serviceBuilders.push(builder as unknown as ServiceBuilder<any, E>)
435
440
 
436
441
  return builder
437
442
  }
@@ -610,7 +615,7 @@ export class Vision<
610
615
  /**
611
616
  * Get Vision context (internal use)
612
617
  */
613
- export function getVisionContext(): VisionContext | undefined {
618
+ export function getVisionContext(): VisionALSContext | undefined {
614
619
  return visionContext.getStore()
615
620
  }
616
621