@virid/express 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -1 +1,265 @@
1
- todo
1
+
2
+
3
+ # **@virid/express**
4
+
5
+ `@virid/express` is an adapter for Express responsible for converting incoming HTTP request messages into Virid’s `HttpRequestMessage`. It also provides a set of dependency injection features similar to NestJS, making the handling of HTTP requests as seamless as processing local Messages.
6
+
7
+ ## 🌟 Core Design Philosophy
8
+
9
+ In `@virid/express`, Express serves merely as a standard I/O layer. Its role is to convert HTTP requests into corresponding Messages and deliver them into the Virid scheduler. Additionally, `@virid/express` provides a set of NestJS-like decorators, allowing HTTP request components—such as the **body** and **query**—to be injected directly into the System.
10
+
11
+ - **HTTP Request to Message:** All HTTP requests are instantiated as specific Messages and dispatched to the scheduler. By using decorators, the Message declaration itself becomes the API definition.
12
+ - **Semantic Return Values:** You can use factory functions like `Ok()`, `NotFound()`, or `StreamFile()` within a System. These are automatically converted into the appropriate HTTP status codes to terminate the request. Alternatively, returning a new `HttpRequestMessage` enables internal request forwarding.
13
+ - **Lifecycle Reference Counting:** To support internal forwarding and redirection, `@virid/express` implements reference-counted lifecycle tracking for every HTTP request. If a request has not been responded to after all Systems finish execution, `@virid/express` will automatically close the connection and throw an error to prevent the request from hanging.
14
+
15
+ ## 🔌Enable plugins
16
+
17
+ ```ts
18
+ import { createVirid } from '@virid/core'
19
+ import { ExpressPlugin } from '@virid/express'
20
+ import express from 'express'
21
+
22
+ const server = express()
23
+ const virid = createVirid()
24
+ .use(ExpressPlugin, { server: server })
25
+ ```
26
+
27
+ ## 🛠️ @virid/express Core API Overview
28
+
29
+ ### **HttpContext**
30
+
31
+ - **Function:** `@virid/express` maintains an `HttpContext` for every HTTP request, containing critical metadata. Whenever a corresponding `System` finishes execution, the Reference Count (**RC**) is automatically decremented by 1. If the RC reaches 0 and the HTTP request has not yet received a response, `@virid/express` will automatically close the connection and log an error message.
32
+ - **Logic:** You can use the `@Ctx()` decorator within a `System` to retrieve the `HttpContext` of the current request.
33
+ - **Example:**
34
+
35
+ ```ts
36
+ export class HttpContext {
37
+ public rc: number = 0;
38
+ public isClosed: boolean = false;
39
+
40
+ constructor(
41
+ public readonly id: number,
42
+ public readonly req: Request,
43
+ public readonly res: Response,
44
+ public readonly timestamp: number,
45
+ public readonly route: string,
46
+ ) {}
47
+ }
48
+ ```
49
+
50
+ ------
51
+
52
+ ### **HttpRequestMessage & @HttpRoute()**
53
+
54
+ - **Function:** `HttpRequestMessage` is a specialized Message type. Every incoming HTTP request is automatically converted into a message of this type. The `@HttpRoute` decorator marks the routing metadata for the `HttpRequestMessage`, including the **path** and **method**.
55
+ - **Logic:** `@HttpRoute` and `HttpRequestMessage` are designed to be used as a pair; `@HttpRoute` can only be applied to classes extending `HttpRequestMessage`. Each `HttpRequestMessage` comes with a `RequestId` type ID, serving as the unique identifier for the current request.
56
+ - **Example:**
57
+
58
+ ```ts
59
+ import { HttpRoute, HttpRequestMessage } from '@virid/express';
60
+
61
+ @HttpRoute({
62
+ path: '/api/login/qr/check',
63
+ method: 'post'
64
+ })
65
+ export class LoginQrCheckRequestMessage extends HttpRequestMessage {}
66
+ ```
67
+
68
+ ### **@HttpSystem()**
69
+
70
+ - **Function:** `@HttpSystem()` differs from the standard `@System()` found in `@virid/core`. It can only be triggered by messages of type `HttpRequestMessage` and supports specialized decorators such as `@Body`, `@Query`, etc.
71
+ - **Logic:** If an error is thrown within an `@HttpSystem`, it is automatically caught and converted into an `InternalServerError()`. Furthermore, `@HttpSystem` supports returning factory functions like `Ok()` or `NotFound()` to directly set response headers and HTTP status codes. It also allows returning a new `HttpRequestMessage` to achieve "request relay" (internal forwarding).
72
+
73
+ #### **Example 1: Parameter Injection**
74
+
75
+ You can inject various HTTP parameters directly into the system method.
76
+
77
+ ```ts
78
+ import { Body, Cookies, Headers, HttpSystem, Ok } from '@virid/express'
79
+
80
+ export class LoginQrCheckSystem {
81
+ @HttpSystem({
82
+ messageClass: LoginQrCheckRequestMessage
83
+ })
84
+ // Directly inject various HTTP parameters into the system
85
+ public static async checkQrStatus(
86
+ @Body() body: LoginQrCheckRequest,
87
+ @Cookies() cookies: Record<string, string>,
88
+ @Headers() headers: Record<string, string>
89
+ ) {
90
+ const { unikey } = body
91
+
92
+ const answer = await createRequest({
93
+ url: '/login/qrcode/client/login',
94
+ data: {
95
+ key: unikey,
96
+ type: 3
97
+ },
98
+ cookies,
99
+ headers
100
+ })
101
+
102
+ // Returns a 200 OK with data and custom headers
103
+ return Ok(answer.data as LoginQrCheckResponse, {
104
+ 'Set-Cookie': answer.cookies
105
+ })
106
+ }
107
+ }
108
+ ```
109
+
110
+ #### **Example 2: Request Relay and Flow Control**
111
+
112
+ This example demonstrates how an HTTP request can flow between different `HttpSystems` using internal message types.
113
+
114
+ ```ts
115
+ // Internal message types used for request flow/relay
116
+ class DataFromLocalMessage extends HttpRequestMessage {
117
+ constructor(
118
+ requestId: RequestId,
119
+ public songId: number
120
+ ) {
121
+ super(requestId)
122
+ }
123
+ }
124
+
125
+ class DataFromCacheMessage extends HttpRequestMessage {
126
+ constructor(
127
+ requestId: RequestId,
128
+ public cachePath: string
129
+ ) {
130
+ super(requestId)
131
+ }
132
+ }
133
+
134
+ // Route Registration
135
+ @HttpRoute({
136
+ path: '/cache/songs/data',
137
+ method: 'get'
138
+ })
139
+ class CacheSongDataRequestMessage extends HttpRequestMessage {}
140
+
141
+ export class CacheSongDataSystem {
142
+ @HttpSystem()
143
+ public static async songData(
144
+ @Message(CacheSongDataRequestMessage) message: CacheSongDataRequestMessage,
145
+ @Query('id') id: number,
146
+ @Query('md5') md5: string,
147
+ @Query('source') source: 'net' | 'local',
148
+ @Headers() headers: Record<string, string>,
149
+ ) {
150
+ const requestId = message.requestId
151
+
152
+ // Relay the request to local logic by returning a new Message
153
+ if (source === 'local') return new DataFromLocalMessage(requestId, id)
154
+
155
+ // Relay to cache logic if a local path exists
156
+ if (localPath) return new DataFromCacheMessage(requestId, localPath)
157
+
158
+ // Otherwise, return a web stream directly
159
+ return Stream(webStream)
160
+ }
161
+
162
+ @HttpSystem()
163
+ public static async songDataFromLocal(
164
+ @Message(DataFromLocalMessage) _message: DataFromLocalMessage,
165
+ dbComponent: DatabaseComponent
166
+ ) {
167
+ // Read file from local storage and return as a file stream
168
+ return StreamFile(absolutePath, {
169
+ dotfiles: 'allow'
170
+ })
171
+ }
172
+
173
+ @HttpSystem()
174
+ public static async songDataFromCache(
175
+ @Message(DataFromCacheMessage) message: DataFromCacheMessage,
176
+ @Query('id') id: number,
177
+ @Query('md5') md5: string,
178
+ dbComponent: DatabaseComponent
179
+ ) {
180
+ // Read from cache file and return as a file stream
181
+ return StreamFile(absolutePath, {
182
+ dotfiles: 'allow'
183
+ })
184
+ }
185
+ ```
186
+
187
+ ### **@Body(), @Query(), and Parameter Decorators**
188
+
189
+ - **Function:** Automatically extracts various information from the incoming request and injects it as arguments into the `HttpSystem` method. This behavior is similar to NestJS decorators.
190
+ - **Example:**
191
+
192
+ ```ts
193
+ export class LoginQrCheckSystem {
194
+ @HttpSystem({
195
+ messageClass: LoginQrCheckRequestMessage
196
+ })
197
+ // You can directly inject various HTTP parameters into the system
198
+ public static async checkQrStatus(
199
+ @Body() body: LoginQrCheckBody,
200
+ @Cookies() cookies: Record<string, string>,
201
+ @Headers() headers: Record<string, string>,
202
+ @Query() id: number,
203
+ @Params() params: LoginQrCheckParams,
204
+ @Req() req: Request,
205
+ @Res() res: Response,
206
+ @Ctx() ctx: HttpContext,
207
+ ) {
208
+ // ....
209
+ return Ok();
210
+ }
211
+ }
212
+ ```
213
+
214
+ ------
215
+
216
+ ### **Pipes**
217
+
218
+ - **Function:** `@virid/express` supports lightweight pipe processing and automatic type conversion. It also allows for custom transformation logic for specific types.
219
+ - **Logic:** When using `@Query()`, `@virid/express` performs automatic type casting. For instance, `@Query() id: number` will automatically be converted to a `number` type. You can also register custom pipes for your own specific types.
220
+ - **Example:**
221
+
222
+ ```ts
223
+ import { addAutoPipe } from '@virid/express';
224
+
225
+ // Register a global transformation for YourType
226
+ addAutoPipe(YourType, (data: any) => {
227
+ // Perform transformation logic here
228
+ return newData;
229
+ });
230
+ ```
231
+
232
+ ------
233
+
234
+ ### 🛜 **Other Response Types**
235
+
236
+ The following factory functions can be used within a System to return standardized HTTP responses:
237
+
238
+ - **`Ok(data, headers)`**: `200 OK`.
239
+ - **`Created(data, headers)`**: `201 Created`.
240
+ - **`NoContent()`**: `204 No Content`.
241
+ - **`BadRequest(msg)`**: `400 Bad Request`.
242
+ - **`Unauthorized(msg)`**: `401 Unauthorized`.
243
+ - **`Forbidden(msg)`**: `403 Forbidden`.
244
+ - **`NotFound(msg)`**: `404 Not Found`.
245
+ - **`InternalServerError(msg)`**: `500 Internal Server Error`.
246
+ - **`CustomResponse(status, data, headers)`**: Returns a response with a custom status code.
247
+ - **`StreamFile(path, options)`**: Sends a local file, automatically handling **Range** requests and **206 Partial Content**.
248
+ - **`Stream(stream, options)`**: Sends a raw `Readable` stream response.
249
+
250
+ #### **Error Handling**
251
+
252
+ The `HttpError` class can be thrown within a system to trigger a specific HTTP status response automatically:
253
+
254
+ TypeScript
255
+
256
+ ```
257
+ export class HttpError extends Error {
258
+ constructor(
259
+ public readonly status: number,
260
+ public readonly message: string,
261
+ ) {
262
+ super(message);
263
+ }
264
+ }
265
+ ```
package/README.zh.md CHANGED
@@ -1 +1,270 @@
1
- todo
1
+ # @virid/express
2
+
3
+ `@virid/express` 是 ` express` 的适配器,负责来自`http`请求的消息转换为`virid`中的`HttpRequestMessage`。并且提供了一组类似`Nestjs`的依赖注入功能。使得处理`http`请求可以像处理本地`Message`一样简单。
4
+
5
+ ## 🌟 核心设计理念
6
+
7
+ 在 `@virid/express` 中,`express`仅充当普通的io层,负责将`http`请求转换为对应的`Message`并投递进入`virid`调度中。`@virid/express`还提供了一组类`Nestjs`的装饰器,使得`http`请求体的`body`、`query`等也可以被注入到`system`中。
8
+
9
+ - **http请求转Message**:所有的`http`请求将被实例化为特定的`Message`并投递进入调度器。使用装饰器实现`Message`声明即API定义。
10
+ - **语义返回值**:可以使用`Ok()`、`NotFound()`、`StreamFile()`等工厂函数从`System`中返回,即可自动转化为相应的`HttpCode`响应并结束`http`请求,或者返回一个新的`HttpRequestMessage`实现请求的内部转发。
11
+ - **生命周期计数**:为了支持消息的内部转发与重定向,`@virid/express`为每个`http`请求实现了引用计数的生命周期跟踪功能。当所有的`System`执行完成后如果`http`请求还未响应,`@virid/express`将自动关闭连接并抛出错误,防止请求挂起。
12
+
13
+ ## 🔌启用插件
14
+
15
+ ```ts
16
+ import { createVirid } from '@virid/core'
17
+ import { ExpressPlugin } from '@virid/express'
18
+ import express from 'express'
19
+
20
+ const server = express()
21
+ const virid = createVirid()
22
+ .use(ExpressPlugin, { server: server })
23
+ ```
24
+
25
+ ## 🛠️ @virid/express 核心 API 概览
26
+
27
+ ### HttpContext
28
+
29
+ - **功能**:`@virid/express`将会每一个`http`请求维护一个`HttpContext`,包含一些重要信息,每当对应的`System`执行完,`rc`将会自动-1,当`rc`减为0时若`http`请求还未响应,`@virid/express`将自动关闭连接并打印错误信息。
30
+ - **逻辑**:你可以使用`@Ctx()`装饰器在System中以获得当前请求的`HttpContext`
31
+ - **示例:**
32
+
33
+ ```ts
34
+ export class HttpContext {
35
+ public rc: number = 0;
36
+ public isClosed: boolean = false;
37
+
38
+ constructor(
39
+ public readonly id: number,
40
+ public readonly req: Request,
41
+ public readonly res: Response,
42
+ public readonly timestamp: number,
43
+ public readonly route: string,
44
+ ) {}
45
+ }
46
+ ```
47
+
48
+ ### `HttpRequestMessage与@HttpRoute()`
49
+
50
+ - **功能**:`HttpRequestMessage`是一种特殊的`Message`类型,每个http请求将被自动转变为一个`HttpRequestMessage`类型的消息。`HttpRoute`则标记了当前`HttpRequestMessage`的路由元信息,包含`path`与`method`等。
51
+ - **逻辑**:`HttpRoute`与`HttpRequestMessage`是成对使用的,`HttpRoute`只能在`HttpRequestMessage`上使用。每个`HttpRequestMessage`将自带一个`RequestId`类型的Id,用以作为当前请求的唯一标记。
52
+ - **示例:**
53
+
54
+ ```ts
55
+ import { HttpRoute, HttpRequestMessage } from '@virid/express'
56
+ @HttpRoute({
57
+ path: '/api/login/qr/check',
58
+ method: 'post'
59
+ })
60
+ export class LoginQrCheckRequestMessage extends HttpRequestMessage {}
61
+ ```
62
+
63
+ ### `@HttpSystem()`
64
+
65
+ - **功能**:`@HttpSystem()`与`@virid/core`中的`@System()`不同。`@HttpSystem()`只能被`HttpRequestMessage`类型的小消息触发,且支持`@Body`、`@Query`等装饰器。
66
+ - **逻辑**:`@HttpSystem()`类型的System中抛出错误后,将自动转换为`InternalServerError()`。且`@HttpSystem()`支持直接返回`OK()`、`NotFound()`等等直接来设置响应头和`HttpCode`,也支持返回新的`HttpRequestMessage`来实现请求接力。
67
+ - **示例:**
68
+
69
+ ```ts
70
+ import { Body, Cookies, Headers, HttpSystem, Ok } from '@virid/express'
71
+
72
+ export class LoginQrCheckSystem {
73
+ @HttpSystem({
74
+ messageClass: LoginQrCheckRequestMessage
75
+ })
76
+ // 可以直接在system中注入各种http参数
77
+ public static async checkQrStatus(
78
+ @Body() body: LoginQrCheckRequest,
79
+ @Cookies() cookies: Record<string, string>,
80
+ @Headers() headers: Record<string, string>
81
+ ) {
82
+ const { unikey } = body
83
+
84
+ const answer = await createRequest({
85
+ url: '/login/qrcode/client/login',
86
+ data: {
87
+ key: unikey,
88
+ type: 3
89
+ },
90
+ cookies,
91
+ headers
92
+ })
93
+ return Ok(answer.data as LoginQrCheckResponse, {
94
+ 'Set-Cookie': answer.cookies
95
+ })
96
+ }
97
+ }
98
+
99
+ ```
100
+
101
+ ```ts
102
+ // 这个示例展示了http请求如何在不同的HttpSystem之间流转
103
+ // 内部的两个用于流转的消息类型
104
+ class DataFromLocalMessage extends HttpRequestMessage {
105
+ constructor(
106
+ requestId: RequestId,
107
+ public songId: number
108
+ ) {
109
+ super(requestId)
110
+ }
111
+ }
112
+ class DataFromCacheMessage extends HttpRequestMessage {
113
+ constructor(
114
+ requestId: RequestId,
115
+ public cachePath: string
116
+ ) {
117
+ super(requestId)
118
+ }
119
+ }
120
+ // 注册路由
121
+ @HttpRoute({
122
+ path: '/cache/songs/data',
123
+ method: 'get'
124
+ })
125
+ class CacheSongDataRequestMessage extends HttpRequestMessage {}
126
+
127
+ export class CacheSongDataSystem {
128
+ @HttpSystem()
129
+ public static async songData(
130
+ @Message(CacheSongDataRequestMessage) message: CacheSongDataRequestMessage,
131
+ @Query('id') id: number,
132
+ @Query('md5') md5: string,
133
+ @Query('source') source: 'net' | 'local',
134
+ @Headers() headers: Record<string, string>,
135
+ ) {
136
+ // 如果是本地歌曲的url,转发http请求
137
+ const requestId = message.requestId
138
+ if (source == 'local') return new DataFromLocalMessage(requestId, id)
139
+ // ...
140
+ // 如果有缓存,走缓存
141
+ if (localPath) return new DataFromCacheMessage(requestId, localPath)
142
+ // ....
143
+ // 返回流对象
144
+ return Stream(webStream)
145
+ }
146
+
147
+ @HttpSystem()
148
+ public static async songDataFromLocal(
149
+ @Message(DataFromLocalMessage) _message: DataFromLocalMessage,
150
+ dbComponent: DatabaseComponent
151
+ ) {
152
+ // ...
153
+ // 从本地读取文件并返回
154
+ return StreamFile(absolutePath, {
155
+ dotfiles: 'allow'
156
+ })
157
+ }
158
+
159
+ @HttpSystem()
160
+ public static async songDataFromCache(
161
+ @Message(DataFromCacheMessage) message: DataFromCacheMessage,
162
+ @Query('id') id: number,
163
+ @Query('md5') md5: string,
164
+ dbComponent: DatabaseComponent
165
+ ) {
166
+ // ....
167
+ // 从缓存文件中读取并返回
168
+ return StreamFile(absolutePath, {
169
+ dotfiles: 'allow'
170
+ })
171
+ }
172
+ }
173
+ ```
174
+
175
+ ### `@Body()/@Query等`
176
+
177
+ - **功能**:自动将请求的各种信息提取并作为`HttpSystem`的参数注入,与`Nestjs`的装饰器相似。
178
+ - **逻辑**:
179
+ - **示例:**
180
+
181
+ ```ts
182
+ export class LoginQrCheckSystem {
183
+ @HttpSystem({
184
+ messageClass: LoginQrCheckRequestMessage
185
+ })
186
+ // 可以直接在system中注入各种http参数
187
+ public static async checkQrStatus(
188
+ @Body() body: LoginQrCheckBody,
189
+ @Cookies() cookies: Record<string, string>,
190
+ @Headers() headers: Record<string, string>,
191
+ @Query() id:number,
192
+ @Params() id:LoginQrCheckParams,
193
+ @Req() req:Request,
194
+ @Res() res:Response,
195
+ @Ctx() ctx: HttpContext,
196
+ ) {
197
+ //....
198
+ return Ok()
199
+ }
200
+ }
201
+ ```
202
+
203
+ ### Pipe
204
+
205
+ - **功能**:`@virid/express`支持简单的pipe处理和自动转换,也支持自定义使用特定类型的pipe转换注册。
206
+ - **逻辑**:在使用`@Query()`时,`@virid/express`支持一些自动的转换,例如 `@Query() id:number`将自动转换为number类型,或者也可以为自己的类型设置相应的`pipe`转换。
207
+ - **示例**:
208
+
209
+ ```ts
210
+ import { addAutoPipe } from '@virid/express'
211
+ addAutoPipe(YourType,(data:YourType)=>{return newData})
212
+ ```
213
+
214
+ ## 🛜其他响应类型
215
+
216
+ ```ts
217
+
218
+ /** 200 OK */
219
+ export const Ok = (data: any, headers: HttpHeaders = {}) =>
220
+ new OkResponse(data, headers);
221
+
222
+ /** 201 Created */
223
+ export const Created = (data: any, headers: HttpHeaders = {}) =>
224
+ new CreatedResponse(data, headers);
225
+
226
+ /** 204 No Content */
227
+ export const NoContent = () => new NoContentResponse();
228
+
229
+ /** 400 Bad Request */
230
+ export const BadRequest = (msg = "Bad Request") => new BadRequestResponse(msg);
231
+
232
+ /** 401 Unauthorized */
233
+ export const Unauthorized = (msg = "Unauthorized") =>
234
+ new UnauthorizedResponse(msg);
235
+
236
+ /** 403 Forbidden */
237
+ export const Forbidden = (msg = "Forbidden") => new ForbiddenResponse(msg);
238
+
239
+ /** 404 Not Found */
240
+ export const NotFound = (msg = "Not Found") => new NotFoundResponse(msg);
241
+
242
+ /** 500 Internal Error */
243
+ export const InternalServerError = (msg = "Internal Server Error") =>
244
+ new InternalServerErrorResponse(msg);
245
+
246
+ export const CustomResponse = (
247
+ status: number,
248
+ data: any,
249
+ headers: HttpHeaders = {},
250
+ ) => new CustomResponseResponse(status, data, headers);
251
+
252
+ /** 发送本地文件 (自动处理 Range/206) */
253
+ export const StreamFile = (path: string, options?: StreamFileOptions) =>
254
+ new StreamFileResponse(path, options);
255
+ /**
256
+ * 发送流响应
257
+ */
258
+ export const Stream = (stream: Readable, options?: StreamResponse["options"]) =>
259
+ new StreamResponse(stream, options);
260
+
261
+ export class HttpError extends Error {
262
+ constructor(
263
+ public readonly status: number,
264
+ public readonly message: string,
265
+ ) {
266
+ super(message);
267
+ }
268
+ }
269
+ ```
270
+
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @virid/express v0.0.1
2
+ * @virid/express v0.1.1
3
3
  * Add express functionality to virid
4
4
  */
5
5
  var Y=Object.defineProperty;var At=Object.getOwnPropertyDescriptor;var Ct=Object.getOwnPropertyNames;var Rt=Object.prototype.hasOwnProperty;var $t=(r,e,t)=>e in r?Y(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var i=(r,e)=>Y(r,"name",{value:e,configurable:!0});var kt=(r,e)=>{for(var t in e)Y(r,t,{get:e[t],enumerable:!0})},Tt=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ct(e))!Rt.call(r,n)&&n!==t&&Y(r,n,{get:()=>e[n],enumerable:!(s=At(e,n))||s.enumerable});return r};var Ht=r=>Tt(Y({},"__esModule",{value:!0}),r);var y=(r,e,t)=>$t(r,typeof e!="symbol"?e+"":e,t);var br={};kt(br,{BadRequest:()=>It,BadRequestResponse:()=>ae,Body:()=>hr,ConflictResponse:()=>Se,Cookies:()=>gr,Created:()=>Vt,CreatedResponse:()=>ne,Ctx:()=>xr,CustomResponse:()=>qt,CustomResponseResponse:()=>ue,ExpressPlugin:()=>Sr,Forbidden:()=>Bt,ForbiddenResponse:()=>ce,Headers:()=>fr,HttpContext:()=>K,HttpError:()=>C,HttpRequestMessage:()=>te,HttpResponse:()=>M,HttpRoute:()=>ur,HttpSystem:()=>pr,InternalServerError:()=>pe,InternalServerErrorResponse:()=>de,NoContent:()=>Pt,NoContentResponse:()=>ie,NotFound:()=>Nt,NotFoundResponse:()=>le,Ok:()=>Ot,OkResponse:()=>se,Params:()=>Er,ParseBoolPipe:()=>mt,ParseIntPipe:()=>gt,Query:()=>Mr,Req:()=>mr,Res:()=>yr,Stream:()=>jt,StreamFile:()=>_t,StreamFileResponse:()=>H,StreamResponse:()=>O,Unauthorized:()=>Dt,UnauthorizedResponse:()=>oe,UnprocessableEntityResponse:()=>be,addAutoPipe:()=>lr,getAutoPipe:()=>ye,parseRawCookie:()=>Ue});module.exports=Ht(br);var Et=require("@virid/core");var Me=require("@virid/core");var $=require("@virid/core");var Ge=require("@virid/core");var Ae=class Ae{constructor(e,t,s,n,o){y(this,"id");y(this,"req");y(this,"res");y(this,"timestamp");y(this,"route");y(this,"rc",0);y(this,"isClosed",!1);this.id=e,this.req=t,this.res=s,this.timestamp=n,this.route=o}inc(){this.rc++}dec(){this.rc--,this.rc===0&&this.tryFinalize()}tryFinalize(){if(this.res.writableEnded||this.isClosed)return;this.isClosed=!0;let e=`[Virid Express] Request Orphaned: The connection was closed because all systems finished execution without sending a response.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @virid/express v0.0.1
2
+ * @virid/express v0.1.1
3
3
  * Add express functionality to virid
4
4
  */
5
5
  var Qe=Object.defineProperty;var xt=(r,e,t)=>e in r?Qe(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var n=(r,e)=>Qe(r,"name",{value:e,configurable:!0});var y=(r,e,t)=>xt(r,typeof e!="symbol"?e+"":e,t);import{MessageWriter as zt}from"@virid/core";import{MessageRegistry as Ut,MessageWriter as Lt}from"@virid/core";import{BaseMessage as Et,MessageWriter as ee}from"@virid/core";import{MessageWriter as Mt}from"@virid/core";var Ee=class Ee{constructor(e,t,s,i,o){y(this,"id");y(this,"req");y(this,"res");y(this,"timestamp");y(this,"route");y(this,"rc",0);y(this,"isClosed",!1);this.id=e,this.req=t,this.res=s,this.timestamp=i,this.route=o}inc(){this.rc++}dec(){this.rc--,this.rc===0&&this.tryFinalize()}tryFinalize(){if(this.res.writableEnded||this.isClosed)return;this.isClosed=!0;let e=`[Virid Express] Request Orphaned: The connection was closed because all systems finished execution without sending a response.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@virid/express",
3
3
  "type": "module",
4
- "version": "0.1.0",
4
+ "version": "0.1.2",
5
5
  "description": "Add express functionality to virid",
6
6
  "author": "Ailrid",
7
7
  "license": "Apache 2.0",
@@ -12,7 +12,7 @@
12
12
  ],
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "git+https://github.com/ArisuYuki/virid.git"
15
+ "url": "git+https://github.com/Ailrid/virid.git"
16
16
  },
17
17
  "main": "./dist/index.cjs",
18
18
  "module": "./dist/index.js",
@@ -35,7 +35,7 @@
35
35
  "peerDependencies": {
36
36
  "express": "^4.17.1 || ^5.0.0",
37
37
  "@types/express": "^5.0.6",
38
- "@virid/core": "0.1.0"
38
+ "@virid/core": "0.1.2"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsup --config tsup.config.ts",