@t4h.framework/dev 0.0.0-experimental-20260901133057 → 0.0.0-experimental-20260902161345
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 +8 -2
- package/README.md +94 -45
- package/dist/AppProcess.d.ts +36 -0
- package/dist/AppProcess.js +125 -0
- package/dist/AppProcess.js.map +1 -0
- package/dist/Server.d.ts +45 -0
- package/dist/Server.js +169 -0
- package/dist/Server.js.map +1 -0
- package/dist/constants/server.d.ts +8 -0
- package/dist/constants/server.js +9 -0
- package/dist/constants/server.js.map +1 -0
- package/dist/http/create-app.d.ts +16 -0
- package/dist/http/create-app.js +83 -0
- package/dist/http/create-app.js.map +1 -0
- package/dist/http/helpers/to-http-error.d.ts +8 -0
- package/dist/http/helpers/to-http-error.js +9 -0
- package/dist/http/helpers/to-http-error.js.map +1 -0
- package/dist/http/middlewares/error-handler.middleware.d.ts +2 -0
- package/dist/http/middlewares/error-handler.middleware.js +27 -0
- package/dist/http/middlewares/error-handler.middleware.js.map +1 -0
- package/dist/http/middlewares/project-manifest.middleware.d.ts +11 -0
- package/dist/http/middlewares/project-manifest.middleware.js +11 -0
- package/dist/http/middlewares/project-manifest.middleware.js.map +1 -0
- package/dist/http/middlewares/read-json-body.middleware.d.ts +6 -0
- package/dist/http/middlewares/read-json-body.middleware.js +22 -0
- package/dist/http/middlewares/read-json-body.middleware.js.map +1 -0
- package/dist/http/middlewares/workflow-authorization.middleware.d.ts +12 -0
- package/dist/http/middlewares/workflow-authorization.middleware.js +28 -0
- package/dist/http/middlewares/workflow-authorization.middleware.js.map +1 -0
- package/dist/index.d.ts +3 -15
- package/dist/index.js +2 -15
- package/dist/index.js.map +1 -1
- package/dist/models/JSONRPCClient.d.ts +2 -0
- package/dist/models/JSONRPCClient.js +21 -4
- package/dist/models/JSONRPCClient.js.map +1 -1
- package/dist/models/JSONRPCError.d.ts +13 -0
- package/dist/models/JSONRPCError.js +11 -0
- package/dist/models/JSONRPCError.js.map +1 -0
- package/dist/models/JSONRPCServer.d.ts +2 -0
- package/dist/models/JSONRPCServer.js +10 -2
- package/dist/models/JSONRPCServer.js.map +1 -1
- package/dist/models/WorkflowAuthorizationMissingError.d.ts +5 -0
- package/dist/models/WorkflowAuthorizationMissingError.js +9 -0
- package/dist/models/WorkflowAuthorizationMissingError.js.map +1 -0
- package/dist/models/WorkflowRun.d.ts +26 -15
- package/dist/models/WorkflowRun.js +15 -8
- package/dist/models/WorkflowRun.js.map +1 -1
- package/dist/models/WorkflowRunActivity.d.ts +37 -27
- package/dist/models/WorkflowRunActivity.js +44 -34
- package/dist/models/WorkflowRunActivity.js.map +1 -1
- package/dist/models/claims/DevORMClaim.d.ts +15 -4
- package/dist/models/claims/DevORMClaim.js +128 -29
- package/dist/models/claims/DevORMClaim.js.map +1 -1
- package/dist/models/claims/DevWorkflowBatchClaim.js +2 -3
- package/dist/models/claims/DevWorkflowBatchClaim.js.map +1 -1
- package/dist/models/claims/DevWorkflowClaim.d.ts +1 -1
- package/dist/models/claims/DevWorkflowClaim.js +6 -11
- package/dist/models/claims/DevWorkflowClaim.js.map +1 -1
- package/dist/repositories/WorkflowRun.repository.d.ts +26 -6
- package/dist/repositories/WorkflowRun.repository.js +162 -11
- package/dist/repositories/WorkflowRun.repository.js.map +1 -1
- package/dist/repositories/WorkflowRunActivity.repository.d.ts +11 -6
- package/dist/repositories/WorkflowRunActivity.repository.js +53 -23
- package/dist/repositories/WorkflowRunActivity.repository.js.map +1 -1
- package/dist/repositories/WorkflowRunAsyncActivityPending.repository.d.ts +26 -0
- package/dist/repositories/WorkflowRunAsyncActivityPending.repository.js +120 -0
- package/dist/repositories/WorkflowRunAsyncActivityPending.repository.js.map +1 -0
- package/dist/services/ActivityRegistry.service.d.ts +7 -0
- package/dist/services/ActivityRegistry.service.js +32 -0
- package/dist/services/ActivityRegistry.service.js.map +1 -0
- package/dist/services/Database.service.d.ts +14 -0
- package/dist/services/Database.service.js +106 -0
- package/dist/services/Database.service.js.map +1 -0
- package/dist/services/TimeoutScheduler.service.js +9 -3
- package/dist/services/TimeoutScheduler.service.js.map +1 -1
- package/dist/services/WorkflowAuthorization.service.d.ts +19 -0
- package/dist/services/WorkflowAuthorization.service.js +75 -0
- package/dist/services/WorkflowAuthorization.service.js.map +1 -0
- package/dist/services/WorkflowRunAsyncActivityFacade.service.d.ts +8 -15
- package/dist/services/WorkflowRunAsyncActivityFacade.service.js +12 -26
- package/dist/services/WorkflowRunAsyncActivityFacade.service.js.map +1 -1
- package/dist/services/WorkflowRunFacade.service.d.ts +73 -7
- package/dist/services/WorkflowRunFacade.service.js +37 -10
- package/dist/services/WorkflowRunFacade.service.js.map +1 -1
- package/dist/services/WorkflowRunLock.service.d.ts +6 -0
- package/dist/services/WorkflowRunLock.service.js +34 -0
- package/dist/services/WorkflowRunLock.service.js.map +1 -0
- package/dist/services/WorkflowRunSyncActivityFacade.service.d.ts +4 -4
- package/dist/services/WorkflowRunSyncActivityFacade.service.js +7 -7
- package/dist/services/WorkflowRunSyncActivityFacade.service.js.map +1 -1
- package/dist/tools/find-workflow-by-id.d.ts +2 -0
- package/dist/tools/find-workflow-by-id.js +9 -0
- package/dist/tools/find-workflow-by-id.js.map +1 -0
- package/dist/tools/format-routes.d.ts +10 -0
- package/dist/tools/format-routes.js +39 -0
- package/dist/tools/format-routes.js.map +1 -0
- package/dist/tools/replace.d.ts +1 -0
- package/dist/tools/replace.js +14 -0
- package/dist/tools/replace.js.map +1 -0
- package/dist/transport/AppProcessJsonRpc.js +41 -0
- package/dist/transport/AppProcessJsonRpc.js.map +1 -0
- package/dist/use-cases/BuildWorkflowRunActivityHistory.usecase.d.ts +9 -0
- package/dist/use-cases/{WorkflowRunBuildHistory.usecase.js → BuildWorkflowRunActivityHistory.usecase.js} +18 -16
- package/dist/use-cases/BuildWorkflowRunActivityHistory.usecase.js.map +1 -0
- package/dist/use-cases/CreateWorkflowRun.usecase.d.ts +4 -6
- package/dist/use-cases/CreateWorkflowRun.usecase.js +14 -22
- package/dist/use-cases/CreateWorkflowRun.usecase.js.map +1 -1
- package/dist/use-cases/CreateWorkflowRunAsyncActivity.usecase.d.ts +9 -3
- package/dist/use-cases/CreateWorkflowRunAsyncActivity.usecase.js +42 -39
- package/dist/use-cases/CreateWorkflowRunAsyncActivity.usecase.js.map +1 -1
- package/dist/use-cases/EnqueueWorkflowRunNextTick.usecase.d.ts +9 -0
- package/dist/use-cases/EnqueueWorkflowRunNextTick.usecase.js +43 -0
- package/dist/use-cases/EnqueueWorkflowRunNextTick.usecase.js.map +1 -0
- package/dist/use-cases/ExecuteWorkflowRunActivity.usecase.d.ts +9 -0
- package/dist/use-cases/ExecuteWorkflowRunActivity.usecase.js +39 -0
- package/dist/use-cases/ExecuteWorkflowRunActivity.usecase.js.map +1 -0
- package/dist/use-cases/ExecuteWorkflowRunAsyncActivity.usecase.d.ts +20 -0
- package/dist/use-cases/ExecuteWorkflowRunAsyncActivity.usecase.js +108 -0
- package/dist/use-cases/ExecuteWorkflowRunAsyncActivity.usecase.js.map +1 -0
- package/dist/use-cases/NextTickWorkflowRun.usecase.d.ts +15 -7
- package/dist/use-cases/NextTickWorkflowRun.usecase.js +139 -128
- package/dist/use-cases/NextTickWorkflowRun.usecase.js.map +1 -1
- package/dist/use-cases/RunWorkflow.usecase.d.ts +10 -0
- package/dist/use-cases/RunWorkflow.usecase.js +46 -0
- package/dist/use-cases/RunWorkflow.usecase.js.map +1 -0
- package/dist/use-cases/WorkflowRunAsyncActivityAdvance.usecase.d.ts +12 -4
- package/dist/use-cases/WorkflowRunAsyncActivityAdvance.usecase.js +41 -27
- package/dist/use-cases/WorkflowRunAsyncActivityAdvance.usecase.js.map +1 -1
- package/dist/use-cases/WorkflowRunFind.usecase.d.ts +32 -0
- package/dist/use-cases/WorkflowRunFind.usecase.js +40 -0
- package/dist/use-cases/WorkflowRunFind.usecase.js.map +1 -0
- package/dist/use-cases/WorkflowRunFindById.usecase.d.ts +53 -0
- package/dist/use-cases/WorkflowRunFindById.usecase.js +83 -0
- package/dist/use-cases/WorkflowRunFindById.usecase.js.map +1 -0
- package/dist/workers/app-process.js +1 -1
- package/dist/workers/app-process.js.map +1 -1
- package/package.json +12 -3
- package/.ai/skills/framework-dev/SKILL.md +0 -348
- package/dist/DevServer.d.ts +0 -24
- package/dist/DevServer.js +0 -87
- package/dist/DevServer.js.map +0 -1
- package/dist/models/InMemoryDatabase.d.ts +0 -20
- package/dist/models/InMemoryDatabase.js +0 -111
- package/dist/models/InMemoryDatabase.js.map +0 -1
- package/dist/services/BuildWorkflowRunResult.service.d.ts +0 -8
- package/dist/services/BuildWorkflowRunResult.service.js +0 -49
- package/dist/services/BuildWorkflowRunResult.service.js.map +0 -1
- package/dist/tools/is-workflow-waiting.d.ts +0 -4
- package/dist/tools/is-workflow-waiting.js +0 -12
- package/dist/tools/is-workflow-waiting.js.map +0 -1
- package/dist/transport/DevServerJsonRpc.js +0 -42
- package/dist/transport/DevServerJsonRpc.js.map +0 -1
- package/dist/use-cases/CallbackWorkflowRunAsyncActivity.usecase.d.ts +0 -14
- package/dist/use-cases/CallbackWorkflowRunAsyncActivity.usecase.js +0 -64
- package/dist/use-cases/CallbackWorkflowRunAsyncActivity.usecase.js.map +0 -1
- package/dist/use-cases/TimeoutWorkflowRunAsyncActivity.usecase.d.ts +0 -8
- package/dist/use-cases/TimeoutWorkflowRunAsyncActivity.usecase.js +0 -40
- package/dist/use-cases/TimeoutWorkflowRunAsyncActivity.usecase.js.map +0 -1
- package/dist/use-cases/WorkflowRunAsyncActivity.usecase.d.ts +0 -7
- package/dist/use-cases/WorkflowRunAsyncActivity.usecase.js +0 -46
- package/dist/use-cases/WorkflowRunAsyncActivity.usecase.js.map +0 -1
- package/dist/use-cases/WorkflowRunBuildHistory.usecase.d.ts +0 -8
- package/dist/use-cases/WorkflowRunBuildHistory.usecase.js.map +0 -1
- package/dist/use-cases/WorkflowRunSyncActivity.usecase.d.ts +0 -4
- package/dist/use-cases/WorkflowRunSyncActivity.usecase.js +0 -28
- package/dist/use-cases/WorkflowRunSyncActivity.usecase.js.map +0 -1
- /package/dist/transport/{DevServerJsonRpc.d.ts → AppProcessJsonRpc.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# @t4h.framework/dev
|
|
2
2
|
|
|
3
|
-
## 0.0.0-experimental-
|
|
3
|
+
## 0.0.0-experimental-20260902161345
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#145](https://github.com/tech4humans-brasil/framework/pull/145) [`13c7a2e`](https://github.com/tech4humans-brasil/framework/commit/13c7a2e80ad5cd3e9ab10ebe5f3cdfc66f4bc664) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - Replaces the interactive REPL of `framework dev` with an HTTP dev server: Hono routes workflow (`POST /projects/:projectId/workflows/:workflowId/runs` answers `201 { id }`, `PATCH .../runs/:runId/activities/:activityId` advances a pending async activity), mandatory workflow authorization resolved from the app/workflow `Authorization` manifest, `/_dev` routes for tooling (manifest, runs, waiting activities, env, SSE events) and Vite in middleware mode for a UI. Workflow runs now live in an in-memory SQLite database inside the app process, the ORM dev claim stores its rows in `db.sqlite` instead of rewriting `db.json` on every change, child workflows run in parallel, and `framework dev` gains `--port` (`PORT`) and `--host`. `DevServer` and `isWorkflowWaiting` are gone; use `Server`.
|
|
8
|
+
|
|
9
|
+
## 0.14.2
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
6
12
|
|
|
7
|
-
- [#143](https://github.com/tech4humans-brasil/framework/pull/143) [`
|
|
13
|
+
- [#143](https://github.com/tech4humans-brasil/framework/pull/143) [`00563fd`](https://github.com/tech4humans-brasil/framework/commit/00563fd9f30cf007a1e5ec8372085cf392d839f4) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - Fix start workflow many interruptions
|
|
8
14
|
|
|
9
15
|
## 0.14.1
|
|
10
16
|
|
package/README.md
CHANGED
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
# @t4h.framework/dev
|
|
2
2
|
|
|
3
|
-
Local development runtime for [T4H Framework](https://github.com/tech4humans-brasil/framework) apps. Watches your project, compiles TypeScript, loads your `App
|
|
3
|
+
Local development runtime for [T4H Framework](https://github.com/tech4humans-brasil/framework) apps. Watches your project, compiles TypeScript, loads your `App` in a child process and exposes it over HTTP with the same routes as the production runtime — no external infrastructure required.
|
|
4
4
|
|
|
5
5
|
## What it does
|
|
6
6
|
|
|
7
7
|
When you run `framework dev` (via `@t4h.framework/cli`), this package powers the experience behind the scenes:
|
|
8
8
|
|
|
9
9
|
1. **TypeScript watch** — compiles your app on every change.
|
|
10
|
-
2. **App process** — forks a child Node process that loads your compiled `App
|
|
11
|
-
3. **
|
|
12
|
-
4. **
|
|
10
|
+
2. **App process** — forks a child Node process that loads your compiled `App` and runs the workflow engine on an in-memory SQLite database.
|
|
11
|
+
3. **HTTP server** — a [Hono](https://hono.dev) app that mirrors the production routes (without the tenant prefix), enforces the workflow authorization and exposes `/_dev` routes for tooling.
|
|
12
|
+
4. **Vite** — a Vite dev server in middleware mode serves everything that is not an API route, ready for a UI plugin.
|
|
13
|
+
5. **Dev claims** — provides local implementations for ORM, HTTP, file system, cache, SMTP, and more.
|
|
13
14
|
|
|
14
15
|
```mermaid
|
|
15
16
|
flowchart TB
|
|
16
|
-
subgraph parent ["Parent process (
|
|
17
|
+
subgraph parent ["Parent process (Server)"]
|
|
17
18
|
Watch["TypeScript watch"]
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
HTTP["Hono (/projects, /_dev)"]
|
|
20
|
+
Vite["Vite middlewares (UI)"]
|
|
21
|
+
Auth["Workflow authorization"]
|
|
22
|
+
Watch -->|"build success"| Fork["AppProcess.up()"]
|
|
23
|
+
HTTP --> Auth
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
subgraph child ["Child process (app-process worker)"]
|
|
25
27
|
App["User App"]
|
|
26
|
-
|
|
28
|
+
Engine["Workflow engine + SQLite :memory:"]
|
|
27
29
|
Claims["Dev claims"]
|
|
28
|
-
App -->
|
|
30
|
+
App --> Engine
|
|
29
31
|
Claims --> App
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
Fork --> App
|
|
35
|
+
HTTP <-->|"IPC / JSON-RPC"| Engine
|
|
33
36
|
```
|
|
34
37
|
|
|
35
38
|
## Installation
|
|
@@ -76,6 +79,8 @@ Then run:
|
|
|
76
79
|
yarn dev
|
|
77
80
|
```
|
|
78
81
|
|
|
82
|
+
The server listens right away and prints the routes of every workflow once the first build finishes.
|
|
83
|
+
|
|
79
84
|
### Options
|
|
80
85
|
|
|
81
86
|
| Flag | Description | Default |
|
|
@@ -83,6 +88,8 @@ yarn dev
|
|
|
83
88
|
| `--entrypoint <path>` | Path to the project's `package.json` | `./package.json` |
|
|
84
89
|
| `-e, --env <KEY=VALUE>` | Environment variable (repeatable) | — |
|
|
85
90
|
| `--env-file-if-exists <path>` | Load variables from a `.env` file if it exists | — |
|
|
91
|
+
| `-p, --port <port>` | HTTP port (also `PORT`) | `3000` |
|
|
92
|
+
| `--host <host>` | HTTP host | `localhost` |
|
|
86
93
|
|
|
87
94
|
Example with env vars:
|
|
88
95
|
|
|
@@ -90,47 +97,89 @@ Example with env vars:
|
|
|
90
97
|
framework dev --entrypoint ./package.json -e API_KEY=secret -e DB_HOST=localhost
|
|
91
98
|
```
|
|
92
99
|
|
|
93
|
-
##
|
|
100
|
+
## HTTP routes
|
|
101
|
+
|
|
102
|
+
The routes are the production ones without the `/tenants/:tenant` and `/versions/:projectVersionId` segments: the dev server has no tenants and a single live version (the last build). `projectId` must match your `App` id.
|
|
103
|
+
|
|
104
|
+
| Method | Route | Authorization | Response |
|
|
105
|
+
|--------|-------|---------------|----------|
|
|
106
|
+
| `GET` | `/projects/:projectId/manifest.json` | no | `200` the app manifest |
|
|
107
|
+
| `POST` | `/projects/:projectId/workflows/:workflowId/runs` | yes | `201 { "id": "<run id>" }` |
|
|
108
|
+
| `PATCH` | `/projects/:projectId/workflows/:workflowId/runs/:runId/activities/:activityId` | yes | `200 { id, type, status }` |
|
|
109
|
+
|
|
110
|
+
The `POST` body is the workflow input, validated against the workflow schema (`400` with the validation errors). The `PATCH` body is `{ "payload": ... }`, validated against the pending async activity schema (`400 Payload is invalid`, `400 AsyncActivity is not pending`). Errors use the NestJS shape `{ statusCode, message, error }`; `503` means the app process is still starting.
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
curl -X POST http://localhost:3000/projects/my-app/workflows/my-workflow/runs \
|
|
114
|
+
-H 'content-type: application/json' \
|
|
115
|
+
-H 'x-signature: <hmac>' \
|
|
116
|
+
-d '{ "userId": "123" }'
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Authorization
|
|
120
|
+
|
|
121
|
+
Every production-mirror route requires an authorization, exactly like the production runtime: the workflow `authorization` wins over the app one, its manifest `pathToModule` is imported and its default export receives the manifest `context` templated with the request (`<< headers.x-signature >>`, `<< rawBody >>`, `<< body.id >>`, `<< params.projectId >>`, `<< query.token >>`). A falsy result or a thrown error answers `401`. A workflow without any authorization answers `500` on purpose: it will not work in production either.
|
|
122
|
+
|
|
123
|
+
`pathToModule` may be `@t4h.framework/hmac/authorize`, `@t4h.framework/jwks/authorize`, `@t4h.framework/oidc/authorize`, an absolute path, a path relative to the project or a `file://` URL.
|
|
124
|
+
|
|
125
|
+
### Dev routes (no authorization)
|
|
94
126
|
|
|
95
|
-
|
|
127
|
+
| Method | Route | Description |
|
|
128
|
+
|--------|-------|-------------|
|
|
129
|
+
| `GET` | `/_dev/manifest` | App manifest |
|
|
130
|
+
| `GET` | `/_dev/state` | `{ state: 'idle' \| 'starting' \| 'ready' \| 'exited' }` |
|
|
131
|
+
| `GET` | `/_dev/runs?status=&workflow=&limit=&offset=` | `{ count, runs }` newest first |
|
|
132
|
+
| `GET` | `/_dev/runs/:id` | Run with activities, pendings and logs (framework tagged JSON) |
|
|
133
|
+
| `GET` | `/_dev/activities/waiting` | Async activities waiting for an advance |
|
|
134
|
+
| `GET` | `/_dev/env` | Environment variables of the app process |
|
|
135
|
+
| `PUT` | `/_dev/env/:name` | `{ value }` sets an environment variable |
|
|
136
|
+
| `GET` | `/_dev/events` | SSE: `manifest`, `build:status`, `build:fail`, `app:exit` |
|
|
137
|
+
|
|
138
|
+
Everything else is handed to Vite, so a UI plugin registered in the project's `vite.config.*` (or through `vite.plugins`) is served by the same port.
|
|
139
|
+
|
|
140
|
+
## State
|
|
141
|
+
|
|
142
|
+
Workflow runs, activities, pending async activities and logs live in an in-memory SQLite database (`node:sqlite`) inside the app process. Every successful build forks a fresh process, so **a rebuild resets all runs, timers and pending activities**; the `manifest` SSE event tells a UI to reload. Durability, queues and resume belong to the production runtime.
|
|
143
|
+
|
|
144
|
+
Sync activities run inline, `sleep` and other timers use `setTimeout`, and child workflows started with `startWorkflow` / `startWorkflowMany` run in parallel, like in production.
|
|
145
|
+
|
|
146
|
+
The ORM claim is the exception: its rows live in `db.sqlite` next to your `package.json` and survive rebuilds and restarts (add it to `.gitignore`). Delete the file to start over. The previous `db.json` is no longer read.
|
|
147
|
+
|
|
148
|
+
## Programmatic usage
|
|
96
149
|
|
|
97
150
|
```typescript
|
|
98
|
-
import {
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
await devServer.start()
|
|
111
|
-
|
|
112
|
-
const result = await devServer.runWorkflow('my-workflow/v1', {
|
|
113
|
-
userId: '123',
|
|
114
|
-
amount: 100,
|
|
151
|
+
import { Server } from '@t4h.framework/dev'
|
|
152
|
+
|
|
153
|
+
const server = new Server({
|
|
154
|
+
entrypoint: './package.json',
|
|
155
|
+
env: { API_KEY: 'secret' },
|
|
156
|
+
port: 3000,
|
|
157
|
+
host: 'localhost',
|
|
158
|
+
vite: { plugins: [myPanelPlugin()] },
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
server.on('manifest', manifest => {
|
|
162
|
+
console.log('App ready:', manifest.workflows.map(workflow => workflow.id))
|
|
115
163
|
})
|
|
116
164
|
|
|
117
|
-
await
|
|
118
|
-
const env = await devServer.listEnv()
|
|
165
|
+
const address = await server.up()
|
|
119
166
|
|
|
120
|
-
|
|
121
|
-
|
|
167
|
+
console.log(address.url)
|
|
168
|
+
|
|
169
|
+
await server.down()
|
|
122
170
|
```
|
|
123
171
|
|
|
124
|
-
###
|
|
172
|
+
### Server API
|
|
125
173
|
|
|
126
|
-
|
|
|
174
|
+
| Member | Description |
|
|
127
175
|
|--------|-------------|
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
|
|
|
133
|
-
|
|
176
|
+
| `up()` | Starts HTTP + Vite, then the TypeScript watch; resolves with `{ host, port, url }`. |
|
|
177
|
+
| `down()` | Stops the watch, the app process, Vite and the HTTP server. |
|
|
178
|
+
| `manifest` | Current app manifest or `null`. |
|
|
179
|
+
| `address` | Listening address (throws before `up()`). |
|
|
180
|
+
| events | `manifest`, `build:status`, `build:fail`, `app:exit`, `error`. |
|
|
181
|
+
|
|
182
|
+
`vite: false` disables Vite; `vite.root` / `vite.configFile` point at another Vite project. The server logs the listening URL, build output and the routes of every workflow through `logger` (default `console`, `false` to silence). A manifest with a workflow that has no authorization (and no app default) emits `error` with a `WorkflowAuthorizationMissingError`; `framework dev` exits with code 1 in that case.
|
|
134
183
|
|
|
135
184
|
## Dev claims
|
|
136
185
|
|
|
@@ -138,7 +187,7 @@ In production, claims are fulfilled by the runtime (database connections, real H
|
|
|
138
187
|
|
|
139
188
|
| Claim | Dev implementation |
|
|
140
189
|
|-------|-------------------|
|
|
141
|
-
| `ORMClaim` |
|
|
190
|
+
| `ORMClaim` | SQLite file `db.sqlite` in the project directory; `where` keeps the Mongo-like semantics (`$like`, `$ilike`, `$or`, ...) |
|
|
142
191
|
| `HttpClientRequestClaim` | Real HTTP via `undici` |
|
|
143
192
|
| `FileSystemClaim` | Local file system with dev binary codec |
|
|
144
193
|
| `SmtpSendEmailClaim` | Captures emails in memory (no delivery) |
|
|
@@ -164,7 +213,7 @@ import {
|
|
|
164
213
|
|
|
165
214
|
## Requirements
|
|
166
215
|
|
|
167
|
-
- Node.js >= 22
|
|
216
|
+
- Node.js >= 22.13 (`node:sqlite`)
|
|
168
217
|
- A T4H Framework `App` exported from your project's entry point (`default` or named `app` export)
|
|
169
218
|
|
|
170
219
|
## License
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { fork } from 'node:child_process';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
import type { App } from '@t4h.framework/core';
|
|
4
|
+
export type AppManifest = ReturnType<App['toManifest']>;
|
|
5
|
+
export type AppProcessState = 'idle' | 'starting' | 'ready' | 'exited';
|
|
6
|
+
export declare class AppProcessNotReadyError extends Error {
|
|
7
|
+
readonly name = "AppProcessNotReadyError";
|
|
8
|
+
}
|
|
9
|
+
export interface AppProcessOptions {
|
|
10
|
+
workerPath?: string;
|
|
11
|
+
readyTimeoutInMs?: number;
|
|
12
|
+
killTimeoutInMs?: number;
|
|
13
|
+
fork?: typeof fork;
|
|
14
|
+
}
|
|
15
|
+
export declare class AppProcess extends EventEmitter {
|
|
16
|
+
private readonly workerPath;
|
|
17
|
+
private readonly readyTimeoutInMs;
|
|
18
|
+
private readonly killTimeoutInMs;
|
|
19
|
+
private readonly forkProcess;
|
|
20
|
+
private readonly server;
|
|
21
|
+
private child;
|
|
22
|
+
private client;
|
|
23
|
+
private ready;
|
|
24
|
+
private currentManifest;
|
|
25
|
+
private currentState;
|
|
26
|
+
constructor({ workerPath, readyTimeoutInMs, killTimeoutInMs, fork: forkProcess, }?: AppProcessOptions);
|
|
27
|
+
get manifest(): AppManifest | null;
|
|
28
|
+
get state(): AppProcessState;
|
|
29
|
+
up(entrypoint: string, env: Record<string, string>): Promise<AppManifest>;
|
|
30
|
+
down(): Promise<void>;
|
|
31
|
+
private kill;
|
|
32
|
+
whenReady(): Promise<AppManifest>;
|
|
33
|
+
call<T = any>(method: string, ...params: any[]): Promise<T>;
|
|
34
|
+
private onManifest;
|
|
35
|
+
private onExit;
|
|
36
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { fork } from 'node:child_process';
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { styleText } from 'node:util';
|
|
5
|
+
import Type from 'typebox';
|
|
6
|
+
import { APP_KILL_TIMEOUT_IN_MS, APP_READY_TIMEOUT_IN_MS, } from './constants/server.js';
|
|
7
|
+
import { JSONRPCClient } from './models/JSONRPCClient.js';
|
|
8
|
+
import { JSONRPCServer, JSONRPCServerMethod } from './models/JSONRPCServer.js';
|
|
9
|
+
export class AppProcessNotReadyError extends Error {
|
|
10
|
+
name = 'AppProcessNotReadyError';
|
|
11
|
+
}
|
|
12
|
+
export class AppProcess extends EventEmitter {
|
|
13
|
+
workerPath;
|
|
14
|
+
readyTimeoutInMs;
|
|
15
|
+
killTimeoutInMs;
|
|
16
|
+
forkProcess;
|
|
17
|
+
server;
|
|
18
|
+
child = null;
|
|
19
|
+
client = null;
|
|
20
|
+
ready = null;
|
|
21
|
+
currentManifest = null;
|
|
22
|
+
currentState = 'idle';
|
|
23
|
+
constructor({ workerPath = path.join(import.meta.dirname, 'workers', 'app-process.js'), readyTimeoutInMs = APP_READY_TIMEOUT_IN_MS, killTimeoutInMs = APP_KILL_TIMEOUT_IN_MS, fork: forkProcess = fork, } = {}) {
|
|
24
|
+
super();
|
|
25
|
+
this.workerPath = workerPath;
|
|
26
|
+
this.readyTimeoutInMs = readyTimeoutInMs;
|
|
27
|
+
this.killTimeoutInMs = killTimeoutInMs;
|
|
28
|
+
this.forkProcess = forkProcess;
|
|
29
|
+
this.server = new JSONRPCServer([
|
|
30
|
+
new JSONRPCServerMethod('manifest', { schema: [Type.Any()] }, (manifest) => this.onManifest(manifest)),
|
|
31
|
+
], message => {
|
|
32
|
+
this.child?.send(message);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
get manifest() {
|
|
36
|
+
return this.currentManifest;
|
|
37
|
+
}
|
|
38
|
+
get state() {
|
|
39
|
+
return this.currentState;
|
|
40
|
+
}
|
|
41
|
+
async up(entrypoint, env) {
|
|
42
|
+
const previous = this.child;
|
|
43
|
+
this.child = null;
|
|
44
|
+
this.client?.rejectPending(new AppProcessNotReadyError('App process is restarting'));
|
|
45
|
+
this.client = null;
|
|
46
|
+
this.ready = Promise.withResolvers();
|
|
47
|
+
this.ready.promise.catch(() => { });
|
|
48
|
+
this.currentState = 'starting';
|
|
49
|
+
await this.kill(previous);
|
|
50
|
+
const child = this.forkProcess(this.workerPath, [
|
|
51
|
+
entrypoint,
|
|
52
|
+
...Object.entries(env).map(([name, value]) => `${name}=${value}`),
|
|
53
|
+
], { stdio: ['ignore', 'inherit', 'inherit', 'ipc'] });
|
|
54
|
+
const client = new JSONRPCClient(message => {
|
|
55
|
+
child.send(message);
|
|
56
|
+
});
|
|
57
|
+
this.child = child;
|
|
58
|
+
this.client = client;
|
|
59
|
+
child.on('message', message => Promise.all([this.server.handle(message), client.handle(message)]).catch(error => {
|
|
60
|
+
console.error(styleText('red', '[AppProcess] failed to handle message:', {
|
|
61
|
+
stream: process.stderr,
|
|
62
|
+
}), error);
|
|
63
|
+
}));
|
|
64
|
+
child.on('exit', code => this.onExit(child, code));
|
|
65
|
+
return this.whenReady();
|
|
66
|
+
}
|
|
67
|
+
async down() {
|
|
68
|
+
await this.kill(this.child);
|
|
69
|
+
}
|
|
70
|
+
async kill(child) {
|
|
71
|
+
if (!child)
|
|
72
|
+
return;
|
|
73
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
74
|
+
return;
|
|
75
|
+
await new Promise(resolve => {
|
|
76
|
+
const timer = setTimeout(() => child.kill('SIGKILL'), this.killTimeoutInMs);
|
|
77
|
+
child.once('exit', () => {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
resolve();
|
|
80
|
+
});
|
|
81
|
+
child.kill();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
whenReady() {
|
|
85
|
+
if (this.currentState === 'ready' && this.currentManifest)
|
|
86
|
+
return Promise.resolve(this.currentManifest);
|
|
87
|
+
if (this.currentState !== 'starting' || !this.ready)
|
|
88
|
+
return Promise.reject(new AppProcessNotReadyError('App process is not running'));
|
|
89
|
+
const { promise } = this.ready;
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const timer = setTimeout(() => reject(new AppProcessNotReadyError(`App process did not become ready in ${this.readyTimeoutInMs}ms`)), this.readyTimeoutInMs);
|
|
92
|
+
promise.then(manifest => {
|
|
93
|
+
clearTimeout(timer);
|
|
94
|
+
resolve(manifest);
|
|
95
|
+
}, error => {
|
|
96
|
+
clearTimeout(timer);
|
|
97
|
+
reject(error);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
async call(method, ...params) {
|
|
102
|
+
await this.whenReady();
|
|
103
|
+
if (!this.client)
|
|
104
|
+
throw new AppProcessNotReadyError('App process is not running');
|
|
105
|
+
return this.client.call(method, ...params);
|
|
106
|
+
}
|
|
107
|
+
onManifest(manifest) {
|
|
108
|
+
this.currentManifest = manifest;
|
|
109
|
+
this.currentState = 'ready';
|
|
110
|
+
this.ready?.resolve(manifest);
|
|
111
|
+
this.emit('manifest', manifest);
|
|
112
|
+
}
|
|
113
|
+
onExit(child, code) {
|
|
114
|
+
if (this.child !== child)
|
|
115
|
+
return;
|
|
116
|
+
const error = new AppProcessNotReadyError(`App process exited with code ${code}`);
|
|
117
|
+
this.child = null;
|
|
118
|
+
this.currentState = 'exited';
|
|
119
|
+
this.client?.rejectPending(error);
|
|
120
|
+
this.client = null;
|
|
121
|
+
this.ready?.reject(error);
|
|
122
|
+
this.emit('exit', code);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=AppProcess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppProcess.js","sourceRoot":"","sources":["../src/AppProcess.ts"],"names":[],"mappings":"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"}
|
package/dist/Server.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { PluginOption } from 'vite';
|
|
3
|
+
import { type AppManifest } from './AppProcess.js';
|
|
4
|
+
export interface ServerViteOptions {
|
|
5
|
+
root?: string;
|
|
6
|
+
configFile?: string | false;
|
|
7
|
+
plugins?: PluginOption[];
|
|
8
|
+
}
|
|
9
|
+
export type ServerLogger = Pick<Console, 'log' | 'error'>;
|
|
10
|
+
export interface ServerOptions {
|
|
11
|
+
entrypoint: string;
|
|
12
|
+
env: Record<string, string>;
|
|
13
|
+
port?: number;
|
|
14
|
+
host?: string;
|
|
15
|
+
vite?: ServerViteOptions | false;
|
|
16
|
+
logger?: ServerLogger | false;
|
|
17
|
+
}
|
|
18
|
+
export interface ServerAddress {
|
|
19
|
+
host: string;
|
|
20
|
+
port: number;
|
|
21
|
+
url: string;
|
|
22
|
+
}
|
|
23
|
+
export declare class Server extends EventEmitter {
|
|
24
|
+
private readonly options;
|
|
25
|
+
private readonly appProcess;
|
|
26
|
+
private readonly logger;
|
|
27
|
+
private routes;
|
|
28
|
+
private tsBuildWatcher;
|
|
29
|
+
private httpServer;
|
|
30
|
+
private vite;
|
|
31
|
+
private currentAddress;
|
|
32
|
+
private packageJsonPath;
|
|
33
|
+
private outDir;
|
|
34
|
+
constructor(options: ServerOptions);
|
|
35
|
+
get manifest(): AppManifest | null;
|
|
36
|
+
get address(): ServerAddress;
|
|
37
|
+
up(): Promise<ServerAddress>;
|
|
38
|
+
down(): Promise<void>;
|
|
39
|
+
private onTsBuildSuccess;
|
|
40
|
+
/**
|
|
41
|
+
* Vite only serves the UI (a panel plugin from the project's vite.config or
|
|
42
|
+
* from `vite.plugins`); the API never goes through it.
|
|
43
|
+
*/
|
|
44
|
+
private createVite;
|
|
45
|
+
}
|
package/dist/Server.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import http from 'node:http';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
5
|
+
import { styleText } from 'node:util';
|
|
6
|
+
import { getRequestListener } from '@hono/node-server';
|
|
7
|
+
import { AppProcess } from './AppProcess.js';
|
|
8
|
+
import { DEFAULT_HOST, DEFAULT_PORT, DEV_ROUTES_PREFIX, PROJECTS_ROUTES_PREFIX, } from './constants/server.js';
|
|
9
|
+
import { createApp } from './http/create-app.js';
|
|
10
|
+
import { WorkflowAuthorizationMissingError } from './models/WorkflowAuthorizationMissingError.js';
|
|
11
|
+
import { formatRoutes } from './tools/format-routes.js';
|
|
12
|
+
import { mkdirOutDirProjectFromTsConfigPathAndJsonPackagePath } from './tools/mkdir-out-dir-project-from-ts-config-path-and-json-package-path.js';
|
|
13
|
+
import { resolvePackageJsonPath } from './tools/resolve-package-json-path.js';
|
|
14
|
+
import { resolveTsconfigFromPackageJsonPath } from './tools/resolve-tsconfig-path-from-package-json-path.js';
|
|
15
|
+
import { tsBuildWatch } from './tools/ts-build-watch.js';
|
|
16
|
+
function isApiPath(pathname) {
|
|
17
|
+
return [PROJECTS_ROUTES_PREFIX, DEV_ROUTES_PREFIX].some(prefix => pathname === prefix || pathname.startsWith(`${prefix}/`));
|
|
18
|
+
}
|
|
19
|
+
function notFound(res) {
|
|
20
|
+
res.statusCode = 404;
|
|
21
|
+
res.setHeader('content-type', 'text/plain; charset=utf-8');
|
|
22
|
+
res.end('Not Found');
|
|
23
|
+
}
|
|
24
|
+
export class Server extends EventEmitter {
|
|
25
|
+
options;
|
|
26
|
+
appProcess = new AppProcess();
|
|
27
|
+
logger;
|
|
28
|
+
routes = [];
|
|
29
|
+
tsBuildWatcher = null;
|
|
30
|
+
httpServer = null;
|
|
31
|
+
vite = null;
|
|
32
|
+
currentAddress = null;
|
|
33
|
+
packageJsonPath = null;
|
|
34
|
+
outDir = null;
|
|
35
|
+
constructor(options) {
|
|
36
|
+
super();
|
|
37
|
+
this.options = options;
|
|
38
|
+
this.logger = options.logger === false ? null : (options.logger ?? console);
|
|
39
|
+
this.appProcess.on('exit', code => {
|
|
40
|
+
if (code)
|
|
41
|
+
this.logger?.error(styleText('red', `[server] app exited with code ${code}`, {
|
|
42
|
+
stream: process.stderr,
|
|
43
|
+
}));
|
|
44
|
+
this.emit('app:exit', code);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
get manifest() {
|
|
48
|
+
return this.appProcess.manifest;
|
|
49
|
+
}
|
|
50
|
+
get address() {
|
|
51
|
+
if (!this.currentAddress)
|
|
52
|
+
throw new Error('Server is not listening');
|
|
53
|
+
return this.currentAddress;
|
|
54
|
+
}
|
|
55
|
+
async up() {
|
|
56
|
+
const { entrypoint, port = DEFAULT_PORT, host = DEFAULT_HOST, vite, } = this.options;
|
|
57
|
+
this.packageJsonPath = await resolvePackageJsonPath(entrypoint);
|
|
58
|
+
const tsConfigPath = await resolveTsconfigFromPackageJsonPath(this.packageJsonPath);
|
|
59
|
+
this.outDir = await mkdirOutDirProjectFromTsConfigPathAndJsonPackagePath(tsConfigPath, this.packageJsonPath);
|
|
60
|
+
const projectDir = path.dirname(this.packageJsonPath);
|
|
61
|
+
const app = createApp({
|
|
62
|
+
appProcess: this.appProcess,
|
|
63
|
+
events: this,
|
|
64
|
+
projectDir,
|
|
65
|
+
});
|
|
66
|
+
this.routes = app.routes;
|
|
67
|
+
const listener = getRequestListener(app.fetch);
|
|
68
|
+
const httpServer = http.createServer((req, res) => {
|
|
69
|
+
const pathname = (req.url ?? '/').split('?')[0] ?? '/';
|
|
70
|
+
if (isApiPath(pathname))
|
|
71
|
+
return void listener(req, res);
|
|
72
|
+
if (!this.vite)
|
|
73
|
+
return notFound(res);
|
|
74
|
+
this.vite.middlewares(req, res, () => notFound(res));
|
|
75
|
+
});
|
|
76
|
+
this.httpServer = httpServer;
|
|
77
|
+
if (vite !== false)
|
|
78
|
+
this.vite = await this.createVite(httpServer, projectDir, vite ?? {});
|
|
79
|
+
await new Promise((resolve, reject) => {
|
|
80
|
+
httpServer.once('error', reject);
|
|
81
|
+
httpServer.listen(port, host, resolve);
|
|
82
|
+
});
|
|
83
|
+
this.currentAddress = { host, port, url: `http://${host}:${port}` };
|
|
84
|
+
this.logger?.log(`[server] listening on ${this.currentAddress.url}, waiting for the first build…`);
|
|
85
|
+
this.tsBuildWatcher = tsBuildWatch(tsConfigPath, {
|
|
86
|
+
outDir: path.join(this.outDir, 'dist'),
|
|
87
|
+
sourceMap: true,
|
|
88
|
+
declaration: false,
|
|
89
|
+
declarationMap: false,
|
|
90
|
+
}, {
|
|
91
|
+
onSuccess: () => this.onTsBuildSuccess(),
|
|
92
|
+
onFail: diagnostics => {
|
|
93
|
+
this.logger?.error(diagnostics);
|
|
94
|
+
this.emit('build:fail', diagnostics);
|
|
95
|
+
},
|
|
96
|
+
onStatus: status => {
|
|
97
|
+
this.logger?.log(status);
|
|
98
|
+
this.emit('build:status', status);
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
return this.currentAddress;
|
|
102
|
+
}
|
|
103
|
+
async down() {
|
|
104
|
+
this.tsBuildWatcher?.close();
|
|
105
|
+
this.tsBuildWatcher = null;
|
|
106
|
+
await this.appProcess.down();
|
|
107
|
+
await this.vite?.close();
|
|
108
|
+
this.vite = null;
|
|
109
|
+
const httpServer = this.httpServer;
|
|
110
|
+
if (httpServer)
|
|
111
|
+
await new Promise((resolve, reject) => {
|
|
112
|
+
httpServer.close(error => (error ? reject(error) : resolve()));
|
|
113
|
+
});
|
|
114
|
+
this.httpServer = null;
|
|
115
|
+
this.currentAddress = null;
|
|
116
|
+
}
|
|
117
|
+
async onTsBuildSuccess() {
|
|
118
|
+
if (!this.packageJsonPath || !this.outDir)
|
|
119
|
+
return;
|
|
120
|
+
const { default: packageJson } = await import(this.packageJsonPath, {
|
|
121
|
+
with: { type: 'json' },
|
|
122
|
+
});
|
|
123
|
+
if (typeof packageJson.main !== 'string')
|
|
124
|
+
throw new Error('Main is not a string');
|
|
125
|
+
const entrypoint = pathToFileURL(path.join(this.outDir, 'dist', packageJson.main)).href;
|
|
126
|
+
let manifest;
|
|
127
|
+
try {
|
|
128
|
+
manifest = await this.appProcess.up(entrypoint, this.options.env);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
this.logger?.error(styleText('red', '[server] app failed to start:', {
|
|
132
|
+
stream: process.stderr,
|
|
133
|
+
}), error);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
for (const workflow of manifest.workflows) {
|
|
137
|
+
if (workflow.authorization || manifest.authorization)
|
|
138
|
+
continue;
|
|
139
|
+
const error = new WorkflowAuthorizationMissingError(String(workflow.id));
|
|
140
|
+
this.logger?.error(styleText('red', `[server] ${error.message}`, {
|
|
141
|
+
stream: process.stderr,
|
|
142
|
+
}));
|
|
143
|
+
this.emit('error', error);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
this.emit('manifest', manifest);
|
|
147
|
+
if (this.logger && this.currentAddress)
|
|
148
|
+
this.logger.log(formatRoutes({
|
|
149
|
+
baseUrl: this.currentAddress.url,
|
|
150
|
+
manifest,
|
|
151
|
+
routes: this.routes,
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Vite only serves the UI (a panel plugin from the project's vite.config or
|
|
156
|
+
* from `vite.plugins`); the API never goes through it.
|
|
157
|
+
*/
|
|
158
|
+
async createVite(httpServer, projectDir, { root = projectDir, configFile, plugins }) {
|
|
159
|
+
const { createServer } = await import('vite');
|
|
160
|
+
return createServer({
|
|
161
|
+
root,
|
|
162
|
+
configFile,
|
|
163
|
+
appType: 'custom',
|
|
164
|
+
server: { middlewareMode: true, hmr: { server: httpServer } },
|
|
165
|
+
plugins,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=Server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Server.js","sourceRoot":"","sources":["../src/Server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const DEFAULT_PORT = 3000;
|
|
2
|
+
export declare const DEFAULT_HOST = "localhost";
|
|
3
|
+
export declare const JSON_BODY_LIMIT_IN_BYTES: number;
|
|
4
|
+
export declare const APP_READY_TIMEOUT_IN_MS = 30000;
|
|
5
|
+
export declare const APP_KILL_TIMEOUT_IN_MS = 5000;
|
|
6
|
+
export declare const SSE_HEARTBEAT_INTERVAL_IN_MS = 15000;
|
|
7
|
+
export declare const PROJECTS_ROUTES_PREFIX = "/projects";
|
|
8
|
+
export declare const DEV_ROUTES_PREFIX = "/_dev";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const DEFAULT_PORT = 3000;
|
|
2
|
+
export const DEFAULT_HOST = 'localhost';
|
|
3
|
+
export const JSON_BODY_LIMIT_IN_BYTES = 150 * 1024;
|
|
4
|
+
export const APP_READY_TIMEOUT_IN_MS = 30_000;
|
|
5
|
+
export const APP_KILL_TIMEOUT_IN_MS = 5_000;
|
|
6
|
+
export const SSE_HEARTBEAT_INTERVAL_IN_MS = 15_000;
|
|
7
|
+
export const PROJECTS_ROUTES_PREFIX = '/projects';
|
|
8
|
+
export const DEV_ROUTES_PREFIX = '/_dev';
|
|
9
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/constants/server.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAA;AAEhC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAA;AAEvC,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,GAAG,IAAI,CAAA;AAElD,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAE7C,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAA;AAE3C,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAA;AAElD,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAA;AAEjD,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAA"}
|