11import type { Operation } from "effection" ;
2- import { all , call , createChannel , each , resource , spawn } from "effection" ;
3-
2+ import { createChannel , each , resource , spawn } from "effection" ;
43import type {
5- LSPAgent ,
64 LSPServerRequest ,
75 NotificationParams ,
8- RequestParams ,
96 RPCEndpoint ,
107} from "./types.ts" ;
11- import { ErrorCodes } from "vscode-jsonrpc" ;
12- import type { InitializeResult } from "vscode-languageserver-protocol" ;
13- import { responseError } from "./json-rpc-connection.ts" ;
14- import * as merge from "./merge.ts" ;
8+ import { lifecycle } from "./lifecycle.ts" ;
159
1610export interface MultiplexerOptions {
1711 servers : RPCEndpoint [ ] ;
@@ -44,8 +38,7 @@ export function useMultiplexer(
4438 }
4539
4640 // delegate notifications and requests from client -> server to current state
47- let states = createChannel < State , never > ( ) ;
48- let state = uninitialized ( servers , states . send ) ;
41+ let [ state , states ] = lifecycle ( servers ) ;
4942
5043 yield * spawn ( function * ( ) {
5144 for ( state of yield * each ( states ) ) {
@@ -68,87 +61,3 @@ export interface State {
6861 notify : RPCEndpoint [ "notify" ] ;
6962 request : RPCEndpoint [ "request" ] ;
7063}
71-
72- function uninitialized (
73- servers : RPCEndpoint [ ] ,
74- transition : ( state : State ) => Operation < void > ,
75- ) : State {
76- return {
77- * notify ( ) { } ,
78- * request < T > ( params : RequestParams ) : Operation < T > {
79- let [ method ] = params ;
80- if ( method !== "initialize" ) {
81- yield * responseError (
82- ErrorCodes . ServerNotInitialized ,
83- `server not initialized` ,
84- ) ;
85- }
86- let agents = yield * all ( servers . map ( ( server ) =>
87- call ( function * ( ) {
88- let initialization = yield * server . request < InitializeResult > (
89- params ,
90- ) ;
91- let { capabilities } = initialization ;
92- return {
93- ...server ,
94- initialization,
95- capabilities,
96- } as LSPAgent ;
97- } )
98- ) ) ;
99-
100- yield * transition ( initialized ( agents , transition ) ) ;
101-
102- return merge . capabilities ( agents ) as T ;
103- } ,
104- } ;
105- }
106-
107- function initialized (
108- agents : LSPAgent [ ] ,
109- transition : ( state : State ) => Operation < void > ,
110- ) : State {
111- return {
112- * notify ( params ) {
113- // TODO: only forward notifications to interested agents
114- for ( let agent of agents ) {
115- yield * agent . notify ( params ) ;
116- }
117- } ,
118- * request ( params ) {
119- let [ first ] = agents ;
120- let [ method ] = params ;
121- if ( method === "initialize" ) {
122- yield * responseError (
123- ErrorCodes . InvalidRequest ,
124- `initialize invoked twice` ,
125- ) ;
126- } else if ( method === "shutdown" ) {
127- yield * transition ( shutdown ) ;
128- for ( let agent of agents ) {
129- yield * agent . request ( params ) ;
130- }
131- return cast ( null ) ;
132- } else if ( ! first ) {
133- throw yield * responseError (
134- ErrorCodes . InternalError ,
135- `no lsps to make requests` ,
136- ) ;
137- }
138-
139- return yield * first . request ( params ) ;
140- } ,
141- } ;
142- }
143-
144- const shutdown : State = {
145- * notify ( ) { } ,
146- * request ( ) {
147- return yield * responseError (
148- ErrorCodes . InvalidRequest ,
149- `server is shut down` ,
150- ) ;
151- } ,
152- } ;
153-
154- const cast = < T > ( value : unknown ) => value as T ;
0 commit comments