@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.
Files changed (187) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +96 -45
  3. package/dist/AppProcess.d.ts +36 -0
  4. package/dist/AppProcess.js +126 -0
  5. package/dist/AppProcess.js.map +1 -0
  6. package/dist/Server.d.ts +41 -0
  7. package/dist/Server.js +168 -0
  8. package/dist/Server.js.map +1 -0
  9. package/dist/constants/server.d.ts +9 -0
  10. package/dist/constants/server.js +10 -0
  11. package/dist/constants/server.js.map +1 -0
  12. package/dist/http/create-app.d.ts +16 -0
  13. package/dist/http/create-app.js +134 -0
  14. package/dist/http/create-app.js.map +1 -0
  15. package/dist/http/helpers/to-http-error.d.ts +8 -0
  16. package/dist/http/helpers/to-http-error.js +9 -0
  17. package/dist/http/helpers/to-http-error.js.map +1 -0
  18. package/dist/http/middlewares/error-handler.middleware.d.ts +2 -0
  19. package/dist/http/middlewares/error-handler.middleware.js +27 -0
  20. package/dist/http/middlewares/error-handler.middleware.js.map +1 -0
  21. package/dist/http/middlewares/project-manifest.middleware.d.ts +11 -0
  22. package/dist/http/middlewares/project-manifest.middleware.js +11 -0
  23. package/dist/http/middlewares/project-manifest.middleware.js.map +1 -0
  24. package/dist/http/middlewares/read-json-body.middleware.d.ts +6 -0
  25. package/dist/http/middlewares/read-json-body.middleware.js +22 -0
  26. package/dist/http/middlewares/read-json-body.middleware.js.map +1 -0
  27. package/dist/http/middlewares/workflow-authorization.middleware.d.ts +12 -0
  28. package/dist/http/middlewares/workflow-authorization.middleware.js +28 -0
  29. package/dist/http/middlewares/workflow-authorization.middleware.js.map +1 -0
  30. package/dist/index.d.ts +3 -15
  31. package/dist/index.js +2 -15
  32. package/dist/index.js.map +1 -1
  33. package/dist/models/JSONRPCClient.d.ts +2 -0
  34. package/dist/models/JSONRPCClient.js +21 -4
  35. package/dist/models/JSONRPCClient.js.map +1 -1
  36. package/dist/models/JSONRPCError.d.ts +13 -0
  37. package/dist/models/JSONRPCError.js +11 -0
  38. package/dist/models/JSONRPCError.js.map +1 -0
  39. package/dist/models/JSONRPCServer.d.ts +2 -0
  40. package/dist/models/JSONRPCServer.js +27 -5
  41. package/dist/models/JSONRPCServer.js.map +1 -1
  42. package/dist/models/WorkflowAuthorizationMissingError.d.ts +5 -0
  43. package/dist/models/WorkflowAuthorizationMissingError.js +9 -0
  44. package/dist/models/WorkflowAuthorizationMissingError.js.map +1 -0
  45. package/dist/models/WorkflowRun.d.ts +28 -15
  46. package/dist/models/WorkflowRun.js +17 -8
  47. package/dist/models/WorkflowRun.js.map +1 -1
  48. package/dist/models/WorkflowRunActivity.d.ts +40 -27
  49. package/dist/models/WorkflowRunActivity.js +46 -34
  50. package/dist/models/WorkflowRunActivity.js.map +1 -1
  51. package/dist/models/claims/DevHttpClientRequestClaim.js +4 -5
  52. package/dist/models/claims/DevHttpClientRequestClaim.js.map +1 -1
  53. package/dist/models/claims/DevORMClaim.d.ts +15 -4
  54. package/dist/models/claims/DevORMClaim.js +128 -29
  55. package/dist/models/claims/DevORMClaim.js.map +1 -1
  56. package/dist/models/claims/DevWorkflowBatchClaim.js +2 -3
  57. package/dist/models/claims/DevWorkflowBatchClaim.js.map +1 -1
  58. package/dist/models/claims/DevWorkflowClaim.d.ts +1 -1
  59. package/dist/models/claims/DevWorkflowClaim.js +6 -11
  60. package/dist/models/claims/DevWorkflowClaim.js.map +1 -1
  61. package/dist/repositories/WorkflowRun.repository.d.ts +41 -6
  62. package/dist/repositories/WorkflowRun.repository.js +204 -11
  63. package/dist/repositories/WorkflowRun.repository.js.map +1 -1
  64. package/dist/repositories/WorkflowRunActivity.repository.d.ts +19 -6
  65. package/dist/repositories/WorkflowRunActivity.repository.js +73 -23
  66. package/dist/repositories/WorkflowRunActivity.repository.js.map +1 -1
  67. package/dist/repositories/WorkflowRunAsyncActivityPending.repository.d.ts +39 -0
  68. package/dist/repositories/WorkflowRunAsyncActivityPending.repository.js +160 -0
  69. package/dist/repositories/WorkflowRunAsyncActivityPending.repository.js.map +1 -0
  70. package/dist/services/ActivityRegistry.service.d.ts +7 -0
  71. package/dist/services/ActivityRegistry.service.js +32 -0
  72. package/dist/services/ActivityRegistry.service.js.map +1 -0
  73. package/dist/services/Database.service.d.ts +14 -0
  74. package/dist/services/Database.service.js +108 -0
  75. package/dist/services/Database.service.js.map +1 -0
  76. package/dist/services/TimeoutScheduler.service.js +9 -3
  77. package/dist/services/TimeoutScheduler.service.js.map +1 -1
  78. package/dist/services/WorkflowAuthorization.service.d.ts +19 -0
  79. package/dist/services/WorkflowAuthorization.service.js +75 -0
  80. package/dist/services/WorkflowAuthorization.service.js.map +1 -0
  81. package/dist/services/WorkflowRunAsyncActivityFacade.service.d.ts +8 -15
  82. package/dist/services/WorkflowRunAsyncActivityFacade.service.js +12 -26
  83. package/dist/services/WorkflowRunAsyncActivityFacade.service.js.map +1 -1
  84. package/dist/services/WorkflowRunEvents.service.d.ts +11 -0
  85. package/dist/services/WorkflowRunEvents.service.js +42 -0
  86. package/dist/services/WorkflowRunEvents.service.js.map +1 -0
  87. package/dist/services/WorkflowRunFacade.service.d.ts +109 -7
  88. package/dist/services/WorkflowRunFacade.service.js +65 -10
  89. package/dist/services/WorkflowRunFacade.service.js.map +1 -1
  90. package/dist/services/WorkflowRunLock.service.d.ts +6 -0
  91. package/dist/services/WorkflowRunLock.service.js +34 -0
  92. package/dist/services/WorkflowRunLock.service.js.map +1 -0
  93. package/dist/services/WorkflowRunSyncActivityFacade.service.d.ts +4 -4
  94. package/dist/services/WorkflowRunSyncActivityFacade.service.js +7 -7
  95. package/dist/services/WorkflowRunSyncActivityFacade.service.js.map +1 -1
  96. package/dist/tools/find-workflow-by-id.d.ts +2 -0
  97. package/dist/tools/find-workflow-by-id.js +9 -0
  98. package/dist/tools/find-workflow-by-id.js.map +1 -0
  99. package/dist/tools/format-routes.d.ts +10 -0
  100. package/dist/tools/format-routes.js +40 -0
  101. package/dist/tools/format-routes.js.map +1 -0
  102. package/dist/tools/replace.d.ts +1 -0
  103. package/dist/tools/replace.js +14 -0
  104. package/dist/tools/replace.js.map +1 -0
  105. package/dist/tools/to-workflow-run-activity-output.d.ts +24 -0
  106. package/dist/tools/to-workflow-run-activity-output.js +18 -0
  107. package/dist/tools/to-workflow-run-activity-output.js.map +1 -0
  108. package/dist/tools/to-workflow-run-output.d.ts +12 -0
  109. package/dist/tools/to-workflow-run-output.js +13 -0
  110. package/dist/tools/to-workflow-run-output.js.map +1 -0
  111. package/dist/transport/AppProcessJsonRpc.js +59 -0
  112. package/dist/transport/AppProcessJsonRpc.js.map +1 -0
  113. package/dist/use-cases/BuildWorkflowRunActivityHistory.usecase.d.ts +9 -0
  114. package/dist/use-cases/{WorkflowRunBuildHistory.usecase.js → BuildWorkflowRunActivityHistory.usecase.js} +18 -16
  115. package/dist/use-cases/BuildWorkflowRunActivityHistory.usecase.js.map +1 -0
  116. package/dist/use-cases/CreateWorkflowRun.usecase.d.ts +6 -6
  117. package/dist/use-cases/CreateWorkflowRun.usecase.js +20 -21
  118. package/dist/use-cases/CreateWorkflowRun.usecase.js.map +1 -1
  119. package/dist/use-cases/CreateWorkflowRunAsyncActivity.usecase.d.ts +9 -3
  120. package/dist/use-cases/CreateWorkflowRunAsyncActivity.usecase.js +45 -39
  121. package/dist/use-cases/CreateWorkflowRunAsyncActivity.usecase.js.map +1 -1
  122. package/dist/use-cases/EnqueueWorkflowRunNextTick.usecase.d.ts +9 -0
  123. package/dist/use-cases/EnqueueWorkflowRunNextTick.usecase.js +43 -0
  124. package/dist/use-cases/EnqueueWorkflowRunNextTick.usecase.js.map +1 -0
  125. package/dist/use-cases/ExecuteWorkflowRunActivity.usecase.d.ts +9 -0
  126. package/dist/use-cases/ExecuteWorkflowRunActivity.usecase.js +46 -0
  127. package/dist/use-cases/ExecuteWorkflowRunActivity.usecase.js.map +1 -0
  128. package/dist/use-cases/ExecuteWorkflowRunAsyncActivity.usecase.d.ts +22 -0
  129. package/dist/use-cases/ExecuteWorkflowRunAsyncActivity.usecase.js +117 -0
  130. package/dist/use-cases/ExecuteWorkflowRunAsyncActivity.usecase.js.map +1 -0
  131. package/dist/use-cases/NextTickWorkflowRun.usecase.d.ts +18 -7
  132. package/dist/use-cases/NextTickWorkflowRun.usecase.js +153 -126
  133. package/dist/use-cases/NextTickWorkflowRun.usecase.js.map +1 -1
  134. package/dist/use-cases/RunWorkflow.usecase.d.ts +10 -0
  135. package/dist/use-cases/RunWorkflow.usecase.js +46 -0
  136. package/dist/use-cases/RunWorkflow.usecase.js.map +1 -0
  137. package/dist/use-cases/WorkflowRunActivityFind.usecase.d.ts +34 -0
  138. package/dist/use-cases/WorkflowRunActivityFind.usecase.js +49 -0
  139. package/dist/use-cases/WorkflowRunActivityFind.usecase.js.map +1 -0
  140. package/dist/use-cases/WorkflowRunActivityFindById.usecase.d.ts +34 -0
  141. package/dist/use-cases/WorkflowRunActivityFindById.usecase.js +60 -0
  142. package/dist/use-cases/WorkflowRunActivityFindById.usecase.js.map +1 -0
  143. package/dist/use-cases/WorkflowRunAsyncActivityAdvance.usecase.d.ts +12 -4
  144. package/dist/use-cases/WorkflowRunAsyncActivityAdvance.usecase.js +41 -27
  145. package/dist/use-cases/WorkflowRunAsyncActivityAdvance.usecase.js.map +1 -1
  146. package/dist/use-cases/WorkflowRunAsyncActivityPendingFind.usecase.d.ts +24 -0
  147. package/dist/use-cases/WorkflowRunAsyncActivityPendingFind.usecase.js +56 -0
  148. package/dist/use-cases/WorkflowRunAsyncActivityPendingFind.usecase.js.map +1 -0
  149. package/dist/use-cases/WorkflowRunFind.usecase.d.ts +18 -0
  150. package/dist/use-cases/WorkflowRunFind.usecase.js +28 -0
  151. package/dist/use-cases/WorkflowRunFind.usecase.js.map +1 -0
  152. package/dist/use-cases/WorkflowRunFindById.usecase.d.ts +21 -0
  153. package/dist/use-cases/WorkflowRunFindById.usecase.js +46 -0
  154. package/dist/use-cases/WorkflowRunFindById.usecase.js.map +1 -0
  155. package/dist/workers/app-process.js +10 -1
  156. package/dist/workers/app-process.js.map +1 -1
  157. package/package.json +14 -4
  158. package/.ai/skills/framework-dev/SKILL.md +0 -348
  159. package/dist/DevServer.d.ts +0 -24
  160. package/dist/DevServer.js +0 -87
  161. package/dist/DevServer.js.map +0 -1
  162. package/dist/models/InMemoryDatabase.d.ts +0 -20
  163. package/dist/models/InMemoryDatabase.js +0 -111
  164. package/dist/models/InMemoryDatabase.js.map +0 -1
  165. package/dist/services/BuildWorkflowRunResult.service.d.ts +0 -8
  166. package/dist/services/BuildWorkflowRunResult.service.js +0 -49
  167. package/dist/services/BuildWorkflowRunResult.service.js.map +0 -1
  168. package/dist/tools/is-workflow-waiting.d.ts +0 -4
  169. package/dist/tools/is-workflow-waiting.js +0 -12
  170. package/dist/tools/is-workflow-waiting.js.map +0 -1
  171. package/dist/transport/DevServerJsonRpc.js +0 -42
  172. package/dist/transport/DevServerJsonRpc.js.map +0 -1
  173. package/dist/use-cases/CallbackWorkflowRunAsyncActivity.usecase.d.ts +0 -14
  174. package/dist/use-cases/CallbackWorkflowRunAsyncActivity.usecase.js +0 -64
  175. package/dist/use-cases/CallbackWorkflowRunAsyncActivity.usecase.js.map +0 -1
  176. package/dist/use-cases/TimeoutWorkflowRunAsyncActivity.usecase.d.ts +0 -8
  177. package/dist/use-cases/TimeoutWorkflowRunAsyncActivity.usecase.js +0 -40
  178. package/dist/use-cases/TimeoutWorkflowRunAsyncActivity.usecase.js.map +0 -1
  179. package/dist/use-cases/WorkflowRunAsyncActivity.usecase.d.ts +0 -7
  180. package/dist/use-cases/WorkflowRunAsyncActivity.usecase.js +0 -46
  181. package/dist/use-cases/WorkflowRunAsyncActivity.usecase.js.map +0 -1
  182. package/dist/use-cases/WorkflowRunBuildHistory.usecase.d.ts +0 -8
  183. package/dist/use-cases/WorkflowRunBuildHistory.usecase.js.map +0 -1
  184. package/dist/use-cases/WorkflowRunSyncActivity.usecase.d.ts +0 -4
  185. package/dist/use-cases/WorkflowRunSyncActivity.usecase.js +0 -28
  186. package/dist/use-cases/WorkflowRunSyncActivity.usecase.js.map +0 -1
  187. /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`, and executes workflows with in-memory claim implementations — no external infrastructure required.
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. **JSON-RPC over IPC** — the parent process drives workflows, env vars, and async activity advancement through a typed RPC layer.
12
- 4. **Dev claims** — provides local implementations for ORM, HTTP, file system, cache, SMTP, and more.
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 (DevServer)"]
17
+ subgraph parent ["Parent process (Server)"]
17
18
  Watch["TypeScript watch"]
18
- RPCClient["JSON-RPC client"]
19
- Watch -->|"build success"| Fork
20
- Fork["fork()"]
21
- Fork --> RPCClient
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
- RPCServer["JSON-RPC server"]
28
+ Engine["Workflow engine + SQLite :memory:"]
27
29
  Claims["Dev claims"]
28
- App --> RPCServer
30
+ App --> Engine
29
31
  Claims --> App
30
32
  end
31
33
 
32
- RPCClient <-->|"IPC / JSON-RPC"| RPCServer
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
- ## Programmatic usage
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
- You can embed `DevServer` in your own tooling instead of using the interactive CLI:
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 { DevServer } from '@t4h.framework/dev'
99
-
100
- const devServer = new DevServer(
101
- {
102
- entrypoint: './package.json',
103
- env: { API_KEY: 'secret' },
104
- },
105
- manifest => {
106
- console.log('App loaded:', manifest.workflows.map(w => w.id))
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 devServer.setEnv('API_KEY', 'new-value')
118
- const env = await devServer.listEnv()
167
+ const address = await server.up()
168
+
169
+ console.log(address.url)
119
170
 
120
- const pending = await devServer.listWaitingAsyncActivities()
121
- await devServer.advanceAsyncActivity(pending[0].id, { approved: true })
171
+ await server.down()
122
172
  ```
123
173
 
124
- ### DevServer API
174
+ ### Server API
125
175
 
126
- | Method | Description |
176
+ | Member | Description |
127
177
  |--------|-------------|
128
- | `start()` | Resolves project paths, starts TypeScript watch, and boots the app process on first successful build. |
129
- | `runWorkflow(id, input)` | Runs a workflow by id with the given input. |
130
- | `setEnv(name, value)` | Sets an environment variable in the running app process. |
131
- | `listEnv()` | Returns all environment variables. |
132
- | `listWaitingAsyncActivities()` | Lists async activities waiting for manual advancement. |
133
- | `advanceAsyncActivity(id, payload)` | Advances a pending async activity with the given payload. |
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` | In-memory database |
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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"}
@@ -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"];