@t4h.framework/dev 0.14.1 → 0.15.0
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 +19 -0
- package/README.md +96 -45
- package/dist/AppProcess.d.ts +36 -0
- package/dist/AppProcess.js +126 -0
- package/dist/AppProcess.js.map +1 -0
- package/dist/Server.d.ts +41 -0
- package/dist/Server.js +168 -0
- package/dist/Server.js.map +1 -0
- package/dist/constants/server.d.ts +9 -0
- package/dist/constants/server.js +10 -0
- package/dist/constants/server.js.map +1 -0
- package/dist/http/create-app.d.ts +16 -0
- package/dist/http/create-app.js +134 -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 +27 -5
- 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 +28 -15
- package/dist/models/WorkflowRun.js +17 -8
- package/dist/models/WorkflowRun.js.map +1 -1
- package/dist/models/WorkflowRunActivity.d.ts +40 -27
- package/dist/models/WorkflowRunActivity.js +46 -34
- package/dist/models/WorkflowRunActivity.js.map +1 -1
- package/dist/models/claims/DevHttpClientRequestClaim.js +4 -5
- package/dist/models/claims/DevHttpClientRequestClaim.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 +41 -6
- package/dist/repositories/WorkflowRun.repository.js +204 -11
- package/dist/repositories/WorkflowRun.repository.js.map +1 -1
- package/dist/repositories/WorkflowRunActivity.repository.d.ts +19 -6
- package/dist/repositories/WorkflowRunActivity.repository.js +73 -23
- package/dist/repositories/WorkflowRunActivity.repository.js.map +1 -1
- package/dist/repositories/WorkflowRunAsyncActivityPending.repository.d.ts +39 -0
- package/dist/repositories/WorkflowRunAsyncActivityPending.repository.js +160 -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 +108 -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/WorkflowRunEvents.service.d.ts +11 -0
- package/dist/services/WorkflowRunEvents.service.js +42 -0
- package/dist/services/WorkflowRunEvents.service.js.map +1 -0
- package/dist/services/WorkflowRunFacade.service.d.ts +109 -7
- package/dist/services/WorkflowRunFacade.service.js +65 -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 +40 -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/tools/to-workflow-run-activity-output.d.ts +24 -0
- package/dist/tools/to-workflow-run-activity-output.js +18 -0
- package/dist/tools/to-workflow-run-activity-output.js.map +1 -0
- package/dist/tools/to-workflow-run-output.d.ts +12 -0
- package/dist/tools/to-workflow-run-output.js +13 -0
- package/dist/tools/to-workflow-run-output.js.map +1 -0
- package/dist/transport/AppProcessJsonRpc.js +59 -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 +6 -6
- package/dist/use-cases/CreateWorkflowRun.usecase.js +20 -21
- 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 +45 -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 +46 -0
- package/dist/use-cases/ExecuteWorkflowRunActivity.usecase.js.map +1 -0
- package/dist/use-cases/ExecuteWorkflowRunAsyncActivity.usecase.d.ts +22 -0
- package/dist/use-cases/ExecuteWorkflowRunAsyncActivity.usecase.js +117 -0
- package/dist/use-cases/ExecuteWorkflowRunAsyncActivity.usecase.js.map +1 -0
- package/dist/use-cases/NextTickWorkflowRun.usecase.d.ts +18 -7
- package/dist/use-cases/NextTickWorkflowRun.usecase.js +153 -126
- 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/WorkflowRunActivityFind.usecase.d.ts +34 -0
- package/dist/use-cases/WorkflowRunActivityFind.usecase.js +49 -0
- package/dist/use-cases/WorkflowRunActivityFind.usecase.js.map +1 -0
- package/dist/use-cases/WorkflowRunActivityFindById.usecase.d.ts +34 -0
- package/dist/use-cases/WorkflowRunActivityFindById.usecase.js +60 -0
- package/dist/use-cases/WorkflowRunActivityFindById.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/WorkflowRunAsyncActivityPendingFind.usecase.d.ts +24 -0
- package/dist/use-cases/WorkflowRunAsyncActivityPendingFind.usecase.js +56 -0
- package/dist/use-cases/WorkflowRunAsyncActivityPendingFind.usecase.js.map +1 -0
- package/dist/use-cases/WorkflowRunFind.usecase.d.ts +18 -0
- package/dist/use-cases/WorkflowRunFind.usecase.js +28 -0
- package/dist/use-cases/WorkflowRunFind.usecase.js.map +1 -0
- package/dist/use-cases/WorkflowRunFindById.usecase.d.ts +21 -0
- package/dist/use-cases/WorkflowRunFindById.usecase.js +46 -0
- package/dist/use-cases/WorkflowRunFindById.usecase.js.map +1 -0
- package/dist/workers/app-process.js +10 -1
- package/dist/workers/app-process.js.map +1 -1
- package/package.json +14 -4
- 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,5 +1,24 @@
|
|
|
1
1
|
# @t4h.framework/dev
|
|
2
2
|
|
|
3
|
+
## 0.15.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#145](https://github.com/tech4humans-brasil/framework/pull/145) [`09724c3`](https://github.com/tech4humans-brasil/framework/commit/09724c3f0bb573d55b94495835362e7b66bc570e) 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
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`a3696b4`](https://github.com/tech4humans-brasil/framework/commit/a3696b48b48598eda9e51c53538a6086abe36018), [`a3696b4`](https://github.com/tech4humans-brasil/framework/commit/a3696b48b48598eda9e51c53538a6086abe36018), [`45182d4`](https://github.com/tech4humans-brasil/framework/commit/45182d4a27c86353747646aa9b70a39bc4c56610)]:
|
|
12
|
+
- @t4h.framework/vite-panel-plugin@0.1.0
|
|
13
|
+
- @t4h.framework/http@0.4.4
|
|
14
|
+
- @t4h.framework/oidc@0.5.0
|
|
15
|
+
|
|
16
|
+
## 0.14.2
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- [#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
|
|
21
|
+
|
|
3
22
|
## 0.14.1
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
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 exposes your workflows (create runs, advance pending activities), enforces the workflow authorization and adds `/_dev` routes for tooling.
|
|
12
|
+
4. **Vite** — a Vite dev server in middleware mode serves the built-in panel and anything else that is not an API route.
|
|
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,91 @@ 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 dev server has no tenants and a single live version (the last build), so the routes carry only the project and the workflow. `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 `/projects` route requires an authorization: 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 is refused when the manifest arrives (the server emits `error`) and answers `500` if reached.
|
|
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=&id=&parentRunId=&parentActivityId=&rootOnly=&createdAfter=&createdBefore=&limit=&offset=` | `{ count, runs }` newest first; `id` is a prefix, `rootOnly=true` hides child runs, `createdAfter`/`createdBefore` are epoch milliseconds |
|
|
132
|
+
| `GET` | `/_dev/runs/:id` | Run with activities (each with its child runs and pendings), logs and `rejectedActivityId` (framework tagged JSON) |
|
|
133
|
+
| `GET` | `/_dev/activities/waiting` | Async activities waiting for an advance |
|
|
134
|
+
| `POST` | `/_dev/workflows/:workflowId/runs` | Starts a run without authorization; body is the input, answers `201 { id }` |
|
|
135
|
+
| `POST` | `/_dev/activities/:activityId/advance` | Advances a pending async activity without authorization; body is `{ payload }` |
|
|
136
|
+
| `GET` | `/_dev/events` | SSE: `manifest`, `build:status`, `build:fail`, `app:exit`, `run:created`, `run:updated` |
|
|
137
|
+
|
|
138
|
+
`run:created` and `run:updated` carry the run summary (the same object `/_dev/runs` lists); updates of one run are coalesced, so a tick that writes several rows produces one event.
|
|
139
|
+
|
|
140
|
+
Everything else is handed to Vite, which serves the panel that ships with this package: open the base URL to browse the workflows and start runs from their schema, follow runs live with the execution trace of each one (activities as a waterfall, child runs nested, input, output, duration, logs, the activity that failed) and advance waiting activities. Plugins from the project's `vite.config.*` (or `vite.plugins`) are served by the same Vite.
|
|
141
|
+
|
|
142
|
+
## State
|
|
143
|
+
|
|
144
|
+
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. There is no durability, queue or resume in the dev server by design.
|
|
145
|
+
|
|
146
|
+
Sync activities run inline, `sleep` and other timers use `setTimeout`, and child workflows started with `startWorkflow` / `startWorkflowMany` run in parallel.
|
|
147
|
+
|
|
148
|
+
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.
|
|
149
|
+
|
|
150
|
+
## Programmatic usage
|
|
96
151
|
|
|
97
152
|
```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,
|
|
153
|
+
import { Server } from '@t4h.framework/dev'
|
|
154
|
+
|
|
155
|
+
const server = new Server({
|
|
156
|
+
entrypoint: './package.json',
|
|
157
|
+
env: { API_KEY: 'secret' },
|
|
158
|
+
port: 3000,
|
|
159
|
+
host: 'localhost',
|
|
160
|
+
vite: { plugins: [myPanelPlugin()] },
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
server.on('manifest', manifest => {
|
|
164
|
+
console.log('App ready:', manifest.workflows.map(workflow => workflow.id))
|
|
115
165
|
})
|
|
116
166
|
|
|
117
|
-
await
|
|
118
|
-
|
|
167
|
+
const address = await server.up()
|
|
168
|
+
|
|
169
|
+
console.log(address.url)
|
|
119
170
|
|
|
120
|
-
|
|
121
|
-
await devServer.advanceAsyncActivity(pending[0].id, { approved: true })
|
|
171
|
+
await server.down()
|
|
122
172
|
```
|
|
123
173
|
|
|
124
|
-
###
|
|
174
|
+
### Server API
|
|
125
175
|
|
|
126
|
-
|
|
|
176
|
+
| Member | Description |
|
|
127
177
|
|--------|-------------|
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
|
|
|
133
|
-
|
|
178
|
+
| `up()` | Starts HTTP + Vite, then the TypeScript watch; resolves with `{ host, port, url }`. |
|
|
179
|
+
| `down()` | Stops the watch, the app process, Vite and the HTTP server. |
|
|
180
|
+
| `manifest` | Current app manifest or `null`. |
|
|
181
|
+
| `address` | Listening address (throws before `up()`). |
|
|
182
|
+
| events | `manifest`, `build:status`, `build:fail`, `app:exit`, `run:created`, `run:updated`, `error`. |
|
|
183
|
+
|
|
184
|
+
`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
185
|
|
|
135
186
|
## Dev claims
|
|
136
187
|
|
|
@@ -138,7 +189,7 @@ In production, claims are fulfilled by the runtime (database connections, real H
|
|
|
138
189
|
|
|
139
190
|
| Claim | Dev implementation |
|
|
140
191
|
|-------|-------------------|
|
|
141
|
-
| `ORMClaim` |
|
|
192
|
+
| `ORMClaim` | SQLite file `db.sqlite` in the project directory; `where` keeps the Mongo-like semantics (`$like`, `$ilike`, `$or`, ...) |
|
|
142
193
|
| `HttpClientRequestClaim` | Real HTTP via `undici` |
|
|
143
194
|
| `FileSystemClaim` | Local file system with dev binary codec |
|
|
144
195
|
| `SmtpSendEmailClaim` | Captures emails in memory (no delivery) |
|
|
@@ -164,7 +215,7 @@ import {
|
|
|
164
215
|
|
|
165
216
|
## Requirements
|
|
166
217
|
|
|
167
|
-
- Node.js >= 22
|
|
218
|
+
- Node.js >= 22.13 (`node:sqlite`)
|
|
168
219
|
- A T4H Framework `App` exported from your project's entry point (`default` or named `app` export)
|
|
169
220
|
|
|
170
221
|
## 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,126 @@
|
|
|
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, WORKFLOW_RUN_EVENTS, } 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
|
+
...WORKFLOW_RUN_EVENTS.map(event => new JSONRPCServerMethod(event, { schema: [Type.Any()] }, (payload) => void this.emit(event, payload))),
|
|
32
|
+
], message => {
|
|
33
|
+
this.child?.send(message);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
get manifest() {
|
|
37
|
+
return this.currentManifest;
|
|
38
|
+
}
|
|
39
|
+
get state() {
|
|
40
|
+
return this.currentState;
|
|
41
|
+
}
|
|
42
|
+
async up(entrypoint, env) {
|
|
43
|
+
const previous = this.child;
|
|
44
|
+
this.child = null;
|
|
45
|
+
this.client?.rejectPending(new AppProcessNotReadyError('App process is restarting'));
|
|
46
|
+
this.client = null;
|
|
47
|
+
this.ready = Promise.withResolvers();
|
|
48
|
+
this.ready.promise.catch(() => { });
|
|
49
|
+
this.currentState = 'starting';
|
|
50
|
+
await this.kill(previous);
|
|
51
|
+
const child = this.forkProcess(this.workerPath, [
|
|
52
|
+
entrypoint,
|
|
53
|
+
...Object.entries(env).map(([name, value]) => `${name}=${value}`),
|
|
54
|
+
], { stdio: ['ignore', 'inherit', 'inherit', 'ipc'] });
|
|
55
|
+
const client = new JSONRPCClient(message => {
|
|
56
|
+
child.send(message);
|
|
57
|
+
});
|
|
58
|
+
this.child = child;
|
|
59
|
+
this.client = client;
|
|
60
|
+
child.on('message', message => Promise.all([this.server.handle(message), client.handle(message)]).catch(error => {
|
|
61
|
+
console.error(styleText('red', '[AppProcess] failed to handle message:', {
|
|
62
|
+
stream: process.stderr,
|
|
63
|
+
}), error);
|
|
64
|
+
}));
|
|
65
|
+
child.on('exit', code => this.onExit(child, code));
|
|
66
|
+
return this.whenReady();
|
|
67
|
+
}
|
|
68
|
+
async down() {
|
|
69
|
+
await this.kill(this.child);
|
|
70
|
+
}
|
|
71
|
+
async kill(child) {
|
|
72
|
+
if (!child)
|
|
73
|
+
return;
|
|
74
|
+
if (child.exitCode !== null || child.signalCode !== null)
|
|
75
|
+
return;
|
|
76
|
+
await new Promise(resolve => {
|
|
77
|
+
const timer = setTimeout(() => child.kill('SIGKILL'), this.killTimeoutInMs);
|
|
78
|
+
child.once('exit', () => {
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
resolve();
|
|
81
|
+
});
|
|
82
|
+
child.kill();
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
whenReady() {
|
|
86
|
+
if (this.currentState === 'ready' && this.currentManifest)
|
|
87
|
+
return Promise.resolve(this.currentManifest);
|
|
88
|
+
if (this.currentState !== 'starting' || !this.ready)
|
|
89
|
+
return Promise.reject(new AppProcessNotReadyError('App process is not running'));
|
|
90
|
+
const { promise } = this.ready;
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
const timer = setTimeout(() => reject(new AppProcessNotReadyError(`App process did not become ready in ${this.readyTimeoutInMs}ms`)), this.readyTimeoutInMs);
|
|
93
|
+
promise.then(manifest => {
|
|
94
|
+
clearTimeout(timer);
|
|
95
|
+
resolve(manifest);
|
|
96
|
+
}, error => {
|
|
97
|
+
clearTimeout(timer);
|
|
98
|
+
reject(error);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async call(method, ...params) {
|
|
103
|
+
await this.whenReady();
|
|
104
|
+
if (!this.client)
|
|
105
|
+
throw new AppProcessNotReadyError('App process is not running');
|
|
106
|
+
return this.client.call(method, ...params);
|
|
107
|
+
}
|
|
108
|
+
onManifest(manifest) {
|
|
109
|
+
this.currentManifest = manifest;
|
|
110
|
+
this.currentState = 'ready';
|
|
111
|
+
this.ready?.resolve(manifest);
|
|
112
|
+
this.emit('manifest', manifest);
|
|
113
|
+
}
|
|
114
|
+
onExit(child, code) {
|
|
115
|
+
if (this.child !== child)
|
|
116
|
+
return;
|
|
117
|
+
const error = new AppProcessNotReadyError(`App process exited with code ${code}`);
|
|
118
|
+
this.child = null;
|
|
119
|
+
this.currentState = 'exited';
|
|
120
|
+
this.client?.rejectPending(error);
|
|
121
|
+
this.client = null;
|
|
122
|
+
this.ready?.reject(error);
|
|
123
|
+
this.emit('exit', code);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# 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,41 @@
|
|
|
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
|
+
private createVite;
|
|
41
|
+
}
|
package/dist/Server.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
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, WORKFLOW_RUN_EVENTS, } 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
|
+
for (const event of WORKFLOW_RUN_EVENTS)
|
|
47
|
+
this.appProcess.on(event, payload => this.emit(event, payload));
|
|
48
|
+
}
|
|
49
|
+
get manifest() {
|
|
50
|
+
return this.appProcess.manifest;
|
|
51
|
+
}
|
|
52
|
+
get address() {
|
|
53
|
+
if (!this.currentAddress)
|
|
54
|
+
throw new Error('Server is not listening');
|
|
55
|
+
return this.currentAddress;
|
|
56
|
+
}
|
|
57
|
+
async up() {
|
|
58
|
+
const { entrypoint, port = DEFAULT_PORT, host = DEFAULT_HOST, vite, } = this.options;
|
|
59
|
+
this.packageJsonPath = await resolvePackageJsonPath(entrypoint);
|
|
60
|
+
const tsConfigPath = await resolveTsconfigFromPackageJsonPath(this.packageJsonPath);
|
|
61
|
+
this.outDir = await mkdirOutDirProjectFromTsConfigPathAndJsonPackagePath(tsConfigPath, this.packageJsonPath);
|
|
62
|
+
const projectDir = path.dirname(this.packageJsonPath);
|
|
63
|
+
const app = createApp({
|
|
64
|
+
appProcess: this.appProcess,
|
|
65
|
+
events: this,
|
|
66
|
+
projectDir,
|
|
67
|
+
});
|
|
68
|
+
this.routes = app.routes;
|
|
69
|
+
const listener = getRequestListener(app.fetch);
|
|
70
|
+
const httpServer = http.createServer((req, res) => {
|
|
71
|
+
const pathname = (req.url ?? '/').split('?')[0] ?? '/';
|
|
72
|
+
if (isApiPath(pathname))
|
|
73
|
+
return void listener(req, res);
|
|
74
|
+
if (!this.vite)
|
|
75
|
+
return notFound(res);
|
|
76
|
+
this.vite.middlewares(req, res, () => notFound(res));
|
|
77
|
+
});
|
|
78
|
+
this.httpServer = httpServer;
|
|
79
|
+
if (vite !== false)
|
|
80
|
+
this.vite = await this.createVite(httpServer, projectDir, vite ?? {});
|
|
81
|
+
await new Promise((resolve, reject) => {
|
|
82
|
+
httpServer.once('error', reject);
|
|
83
|
+
httpServer.listen(port, host, resolve);
|
|
84
|
+
});
|
|
85
|
+
this.currentAddress = { host, port, url: `http://${host}:${port}` };
|
|
86
|
+
this.logger?.log(`[server] listening on ${this.currentAddress.url}, waiting for the first build…`);
|
|
87
|
+
this.tsBuildWatcher = tsBuildWatch(tsConfigPath, {
|
|
88
|
+
outDir: path.join(this.outDir, 'dist'),
|
|
89
|
+
sourceMap: true,
|
|
90
|
+
declaration: false,
|
|
91
|
+
declarationMap: false,
|
|
92
|
+
}, {
|
|
93
|
+
onSuccess: () => this.onTsBuildSuccess(),
|
|
94
|
+
onFail: diagnostics => {
|
|
95
|
+
this.logger?.error(diagnostics);
|
|
96
|
+
this.emit('build:fail', diagnostics);
|
|
97
|
+
},
|
|
98
|
+
onStatus: status => {
|
|
99
|
+
this.logger?.log(status);
|
|
100
|
+
this.emit('build:status', status);
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
return this.currentAddress;
|
|
104
|
+
}
|
|
105
|
+
async down() {
|
|
106
|
+
this.tsBuildWatcher?.close();
|
|
107
|
+
this.tsBuildWatcher = null;
|
|
108
|
+
await this.appProcess.down();
|
|
109
|
+
await this.vite?.close();
|
|
110
|
+
this.vite = null;
|
|
111
|
+
const httpServer = this.httpServer;
|
|
112
|
+
if (httpServer)
|
|
113
|
+
await new Promise((resolve, reject) => {
|
|
114
|
+
httpServer.close(error => (error ? reject(error) : resolve()));
|
|
115
|
+
});
|
|
116
|
+
this.httpServer = null;
|
|
117
|
+
this.currentAddress = null;
|
|
118
|
+
}
|
|
119
|
+
async onTsBuildSuccess() {
|
|
120
|
+
if (!this.packageJsonPath || !this.outDir)
|
|
121
|
+
return;
|
|
122
|
+
const { default: packageJson } = await import(this.packageJsonPath, {
|
|
123
|
+
with: { type: 'json' },
|
|
124
|
+
});
|
|
125
|
+
if (typeof packageJson.main !== 'string')
|
|
126
|
+
throw new Error('Main is not a string');
|
|
127
|
+
const entrypoint = pathToFileURL(path.join(this.outDir, 'dist', packageJson.main)).href;
|
|
128
|
+
let manifest;
|
|
129
|
+
try {
|
|
130
|
+
manifest = await this.appProcess.up(entrypoint, this.options.env);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
this.logger?.error(styleText('red', '[server] app failed to start:', {
|
|
134
|
+
stream: process.stderr,
|
|
135
|
+
}), error);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
for (const workflow of manifest.workflows) {
|
|
139
|
+
if (workflow.authorization || manifest.authorization)
|
|
140
|
+
continue;
|
|
141
|
+
const error = new WorkflowAuthorizationMissingError(String(workflow.id));
|
|
142
|
+
this.logger?.error(styleText('red', `[server] ${error.message}`, {
|
|
143
|
+
stream: process.stderr,
|
|
144
|
+
}));
|
|
145
|
+
this.emit('error', error);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
this.emit('manifest', manifest);
|
|
149
|
+
if (this.logger && this.currentAddress)
|
|
150
|
+
this.logger.log(formatRoutes({
|
|
151
|
+
baseUrl: this.currentAddress.url,
|
|
152
|
+
manifest,
|
|
153
|
+
routes: this.routes,
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
async createVite(httpServer, projectDir, { root = projectDir, configFile, plugins }) {
|
|
157
|
+
const { createServer } = await import('vite');
|
|
158
|
+
const { default: panel } = await import('@t4h.framework/vite-panel-plugin');
|
|
159
|
+
return createServer({
|
|
160
|
+
root,
|
|
161
|
+
configFile,
|
|
162
|
+
appType: 'custom',
|
|
163
|
+
server: { middlewareMode: true, hmr: { server: httpServer } },
|
|
164
|
+
plugins: [panel(), ...(plugins ?? [])],
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# 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,9 @@
|
|
|
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";
|
|
9
|
+
export declare const WORKFLOW_RUN_EVENTS: readonly ["run:created", "run:updated"];
|