| ... | ... | @@ -183,23 +183,22 @@ export const createServer = Effect.fn(function* (options: ServerOptions = {}): E |
| 183 | 183 | }); |
| 184 | 184 | } |
| 185 | 185 | |
| 186 | | const onTerminalEvent = (event: TerminalEvent) => |
| 187 | | Effect.gen(function* () { |
| 188 | | const push: WsPush = { |
| 189 | | type: "push", |
| 190 | | channel: WS_CHANNELS.terminalEvent, |
| 191 | | data: event, |
| 192 | | }; |
| 193 | | const message = yield* Schema.encodeEffect(Schema.fromJsonString(WsPush))(push); |
| 194 | | let recipients = 0; |
| 195 | | for (const client of yield* Ref.get(clients)) { |
| 196 | | if (client.readyState === client.OPEN) { |
| 197 | | client.send(message); |
| 198 | | recipients += 1; |
| 199 | | } |
| 186 | const onTerminalEvent = Effect.fnUntraced(function* (event: TerminalEvent) { |
| 187 | const push: WsPush = { |
| 188 | type: "push", |
| 189 | channel: WS_CHANNELS.terminalEvent, |
| 190 | data: event, |
| 191 | }; |
| 192 | const message = yield* Schema.encodeEffect(Schema.fromJsonString(WsPush))(push); |
| 193 | let recipients = 0; |
| 194 | for (const client of yield* Ref.get(clients)) { |
| 195 | if (client.readyState === client.OPEN) { |
| 196 | client.send(message); |
| 197 | recipients += 1; |
| 200 | 198 | } |
| 201 | | logOutgoingPush(push, recipients); |
| 202 | | }).pipe(Effect.runPromise); |
| 199 | } |
| 200 | logOutgoingPush(push, recipients); |
| 201 | }); |
| 203 | 202 | |
| 204 | 203 | // HTTP server — serves static files or redirects to Vite dev server |
| 205 | 204 | const httpServer = http.createServer((req, res) => { |
| ... | ... | @@ -289,9 +288,7 @@ export const createServer = Effect.fn(function* (options: ServerOptions = {}): E |
| 289 | 288 | const { openInEditor } = yield* Open; |
| 290 | 289 | |
| 291 | 290 | const subscriptionsScope = yield* Scope.make("sequential"); |
| 292 | | yield* Effect.addFinalizer(() => |
| 293 | | Scope.close(subscriptionsScope, Exit.void).pipe(Effect.orElseSucceed(() => undefined)), |
| 294 | | ); |
| 291 | yield* Effect.addFinalizer(() => Scope.close(subscriptionsScope, Exit.void)); |
| 295 | 292 | |
| 296 | 293 | yield* Stream.runForEach(orchestrationEngine.streamDomainEvents, (event) => |
| 297 | 294 | Effect.gen(function* () { |
| ... | ... | @@ -312,7 +309,7 @@ export const createServer = Effect.fn(function* (options: ServerOptions = {}): E |
| 312 | 309 | }), |
| 313 | 310 | ).pipe(Effect.forkIn(subscriptionsScope)); |
| 314 | 311 | |
| 315 | | yield* orchestrationReactor.start.pipe(Scope.provide(subscriptionsScope)); |
| 312 | yield* Scope.provide(orchestrationReactor.start, subscriptionsScope); |
| 316 | 313 | |
| 317 | 314 | if (autoBootstrapProjectFromCwd) { |
| 318 | 315 | const snapshot = yield* projectionReadModelQuery.getSnapshot(); |
| ... | ... | @@ -332,7 +329,7 @@ export const createServer = Effect.fn(function* (options: ServerOptions = {}): E |
| 332 | 329 | } |
| 333 | 330 | } |
| 334 | 331 | |
| 335 | | const routeRequest = Effect.fn(function* (request: WebSocketRequest) { |
| 332 | const routeRequest = Effect.fnUntraced(function* (request: WebSocketRequest) { |
| 336 | 333 | switch (request.body._tag) { |
| 337 | 334 | case ORCHESTRATION_WS_METHODS.getSnapshot: |
| 338 | 335 | return yield* projectionReadModelQuery.getSnapshot(); |
| ... | ... | @@ -573,18 +570,24 @@ export const createServer = Effect.fn(function* (options: ServerOptions = {}): E |
| 573 | 570 | ), |
| 574 | 571 | ); |
| 575 | 572 | |
| 576 | | const unsubscribeTerminalEvents = yield* terminalManager.subscribe(onTerminalEvent); |
| 573 | const unsubscribeTerminalEvents = yield* terminalManager.subscribe( |
| 574 | (event) => void Effect.runPromise(onTerminalEvent(event)), |
| 575 | ); |
| 577 | 576 | yield* Effect.addFinalizer(() => |
| 578 | | Effect.sync(() => { |
| 579 | | unsubscribeTerminalEvents(); |
| 580 | | }), |
| 577 | Effect.all([Effect.sync(() => unsubscribeTerminalEvents()), terminalManager.dispose()]), |
| 581 | 578 | ); |
| 582 | | yield* Effect.addFinalizer(terminalManager.dispose); |
| 583 | 579 | |
| 584 | 580 | yield* NodeHttpServer.make(() => httpServer, listenOptions); |
| 585 | 581 | |
| 586 | 582 | yield* Effect.addFinalizer(() => |
| 587 | | Effect.all([closeAllClients, closeWebSocketServer.pipe(Effect.orElseSucceed(() => undefined))]), |
| 583 | Effect.all([ |
| 584 | closeAllClients, |
| 585 | closeWebSocketServer.pipe( |
| 586 | Effect.catch((error) => |
| 587 | Effect.logWarning("failed to close web socket server", { cause: error }), |
| 588 | ), |
| 589 | ), |
| 590 | ]), |
| 588 | 591 | ); |
| 589 | 592 | |
| 590 | 593 | return httpServer; |