You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: packages/server/README.md
+22-19Lines changed: 22 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,7 +15,11 @@ Key points:
15
15
16
16
-`useServiceGraph(services: ServicesMap, options?: { sequential?: boolean }): ServiceRunner<ServicesMap>` — returns a _runner function_ which you call to start the graph: `const run = useServiceGraph(services, options); yield* run(subset?: string[] | string);`. By default services in the same topological layer run concurrently; pass `options.sequential = true` to run services in each layer serially.
17
17
-`ServiceDefinition.operation` (required) — an `Operation<void>` which indicates the service has started. This operation may be long-lived (e.g. `useService`) or may return once the service is ready while a background child keeps the service running. See the example below.
18
-
-`deps` — an optional list of service names this service depends on; services without dependencies in the same layer are started concurrently by default, or serially when `options.sequential` is true.
18
+
-`dependsOn` — an optional object `{ startup: string[]; restart?: string[] }` listing service names this service depends on. Use `startup` to list services that must start before this service; use `restart` to list services that should trigger a restart of this service when they are restarted (for example, due to a watched file change). Services without dependencies in the same layer are started concurrently by default, or serially when `options.sequential` is true.
19
+
20
+
-`subset` (runner argument) — when calling the runner returned by `useServiceGraph` you may pass a subset (e.g. `yield* run(['serviceA'])` or `yield* run('serviceA')`) to start only a subset of services; any startup dependencies required by that subset are automatically included.
21
+
22
+
- Watching & restart propagation — pass `{ watch: true }` to `useServiceGraph` and define `watch` paths in each `ServiceDefinition` to enable file watching. The watcher will precompute transitive dependents (based on `dependsOn.restart`) and automatically emit restart updates for dependents when a watched path changes, so restarts propagate efficiently and deterministically.
19
23
- Lifecycle hooks: `beforeStart`, `afterStart`, `beforeStop`, `afterStop` — each is an `Operation<void>` that runs at the appropriate time.
20
24
21
25
Example:
@@ -42,7 +46,7 @@ main(function* () {
42
46
"B",
43
47
"node --import tsx ./test/services/service-b.ts"
44
48
),
45
-
deps: ["A"],
49
+
dependsOn: { startup: ["A"] },
46
50
},
47
51
});
48
52
});
@@ -61,29 +65,28 @@ Each `ServiceDefinition` supports lifecycle hook operations. These hooks run in
61
65
```ts
62
66
const services = {
63
67
A: {
64
-
operation: useService(
65
-
"A",
66
-
"node --import tsx ./test/services/service-a.ts"
67
-
),
68
-
afterStart: () =>
69
-
(function* () {
70
-
// runs after the operation returns
71
-
console.log("A has started");
72
-
})(),
73
-
beforeStop: () =>
74
-
(function* () {
75
-
// runs during shutdown in reverse order
68
+
operation: (function* () {
69
+
// start the service via useService or useChildSimulation
Previously services could expose their return value via a public `exportsOperation` that consumers could await. That mechanism has been removed in this branch as we move to a child-process-focused runner model. Provider-returned values are still delivered to dependent service factories internally, but no longer exposed as an operation on the public `services` map.
134
137
135
-
For convenience tests may use the `servicePorts` map exposed by the running graph to discover HTTP ports that services registered when they start.
138
+
For convenience tests may use the `servicePorts` map exposed by the running graph to discover HTTP ports that services registered when they start. The `servicePorts` map is available on the object returned by the runner and contains service name => port when a service's `operation` returns an object with a `{ port: number }` property.
Copy file name to clipboardExpand all lines: packages/server/example/README.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ This folder contains runnable examples demonstrating `useServiceGraph` and `useS
4
4
5
5
There are two sets of examples:
6
6
7
-
-**use-service** (top-level files like `basic-graph.ts`, `lifecycle-hooks.ts`, `concurrency-layers.ts`) — these spawn separate processes using `useService` (e.g. `node --import tsx ./example/services/*.ts`). Use these to exercise the process-based behavior.
7
+
-**use-service** (top-level files like `basic-graph.ts`, `concurrency-layers.ts`) — these spawn separate processes using `useService` (e.g. `node --import tsx ./example/services/*.ts`). Use these to exercise the process-based behavior.
8
8
9
9
-**operation** (under `operation/`) — these demonstrate `useChildSimulation()` which runs each service in a child process using a simulation factory. They show how to isolate simulations and start them as independent processes.
These examples make use of the small service implementations in `./example/services`.
28
+
29
+
Notes: the examples now use `dependsOn` with a `{ startup, restart? }` shape. To experiment with restart propagation, add a `watch` entry to a service and include dependents via `dependsOn.restart` — when a watched file changes the watcher will restart the affected service and its transitive dependents.
0 commit comments