@@ -16,35 +16,39 @@ export enum ConnectionState {
1616// Note that we trust that server returns well-formed JSON. It would take far too much time to
1717// verify its adherence to the schema here, for little gain.
1818export class Connection {
19+ private readonly link :link . ILink ;
20+
1921private _state = ConnectionState . Initializing ;
2022
2123private _commands :string [ ] = [ ] ;
2224private _events :string [ ] = [ ] ;
2325private _itemValuesEncodings :string [ ] = [ ] ;
2426
2527private promises :{
26- resolve :( response :proto . AnyResponse ) => void ;
28+ resolve :( response :link . Packet < proto . AnyResponse > ) => void ;
2729reject :( error :Error ) => void ;
2830} [ ] = [ ] ;
2931private timestamps :Date [ ] = [ ] ;
3032
3133private sendIndex :number = 0 ;
3234private recvIndex :number = 0 ;
3335
34- constructor ( private readonly link :link . ILink ) {
36+ constructor ( link_ :link . ILink ) {
37+ this . link = link_ ;
3538this . link . onRecv = this . onLinkRecv . bind ( this ) ;
3639this . link . onDone = this . onLinkDone . bind ( this ) ;
37- this . send ( {
40+ this . send ( link . Packet . fromObject ( {
3841type :'greeting' ,
3942version :0 ,
40- } ) ;
43+ } ) ) ;
4144}
4245
4346dispose ( ) :void {
4447this . link . dispose ( ) ;
4548}
4649
47- private traceSend ( packet :proto . ClientPacket ) {
50+ private traceSend ( linkPacket :link . Packet < proto . ClientPacket > ) {
51+ const packet = linkPacket . asObject ( ) ;
4852if ( packet . type === 'greeting' ) {
4953console . debug ( '[CXXRTL] C>S' , packet ) ;
5054} else if ( packet . type === 'command' ) {
@@ -53,7 +57,8 @@ export class Connection {
5357}
5458}
5559
56- private traceRecv ( packet :proto . ServerPacket ) {
60+ private traceRecv ( linkPacket :link . Packet < proto . ServerPacket > ) {
61+ const packet = linkPacket . asObject ( ) ;
5762if ( packet . type === 'greeting' ) {
5863console . debug ( '[CXXRTL] S>C' , packet ) ;
5964} else if ( packet . type === 'response' ) {
@@ -67,17 +72,18 @@ export class Connection {
6772}
6873}
6974
70- private async send ( packet : proto . ClientPacket ) :Promise < void > {
71- this . traceSend ( packet ) ;
75+ private async send ( linkPacket : link . Packet < proto . ClientPacket > ) :Promise < void > {
76+ this . traceSend ( linkPacket ) ;
7277if ( this . _state === ConnectionState . Disconnected ) {
7378throw new Error ( 'unable to send packet after link is shutdown' ) ;
7479} else {
75- this . link . send ( packet ) ;
80+ this . link . send ( linkPacket ) ;
7681}
7782}
7883
79- private async onLinkRecv ( packet :proto . ServerPacket ) :Promise < void > {
80- this . traceRecv ( packet ) ;
84+ private async onLinkRecv ( linkPacket :link . Packet < proto . ServerPacket > ) :Promise < void > {
85+ this . traceRecv ( linkPacket ) ;
86+ const packet = linkPacket . asObject ( ) ;
8187if ( this . _state === ConnectionState . Initializing && packet . type === 'greeting' ) {
8288if ( packet . version === 0 ) {
8389this . _commands = packet . commands ;
@@ -93,15 +99,15 @@ export class Connection {
9399const nextPromise = this . promises . shift ( ) ;
94100if ( nextPromise !== undefined ) {
95101if ( packet . type === 'response' ) {
96- nextPromise . resolve ( packet ) ;
102+ nextPromise . resolve ( link . Packet . fromObject ( packet ) ) ;
97103} else {
98104nextPromise . reject ( new CommandError ( packet ) ) ;
99105}
100106} else {
101107this . rejectPromises ( new Error ( `unexpected '${ packet . type } ' reply with no commands queued` ) ) ;
102108}
103109} else if ( this . _state === ConnectionState . Connected && packet . type === 'event' ) {
104- await this . onEvent ( packet ) ;
110+ await this . onEvent ( link . Packet . fromObject ( packet ) ) ;
105111} else {
106112this . rejectPromises ( new Error ( `unexpected${ packet . type } packet received for${ this . _state } connection` ) ) ;
107113}
@@ -119,7 +125,7 @@ export class Connection {
119125}
120126}
121127
122- async perform ( command :proto . AnyCommand ) :Promise < proto . AnyResponse > {
128+ async exchange ( command :link . Packet < proto . AnyCommand > ) :Promise < link . Packet < proto . AnyResponse > > {
123129await this . send ( command ) ;
124130return new Promise ( ( resolve , reject ) => {
125131this . promises . push ( { resolve, reject} ) ;
@@ -130,7 +136,7 @@ export class Connection {
130136
131137async onDisconnected ( ) :Promise < void > { }
132138
133- async onEvent ( _event :proto . AnyEvent ) :Promise < void > { }
139+ async onEvent ( _event :link . Packet < proto . AnyEvent > ) :Promise < void > { }
134140
135141get state ( ) :ConnectionState {
136142return this . _state ;
@@ -148,31 +154,36 @@ export class Connection {
148154return this . _itemValuesEncodings . slice ( ) ;
149155}
150156
157+ private async command < T extends proto . AnyResponse > ( command :proto . AnyCommand ) :Promise < T > {
158+ const response = await this . exchange ( link . Packet . fromObject ( command ) ) ;
159+ return response . cast < T > ( ) . asObject ( ) ;
160+ }
161+
151162async listScopes ( command :proto . CommandListScopes ) :Promise < proto . ResponseListScopes > {
152- return await this . perform ( command ) as proto . ResponseListScopes ;
163+ return this . command < proto . ResponseListScopes > ( command ) ;
153164}
154165
155166async listItems ( command :proto . CommandListItems ) :Promise < proto . ResponseListItems > {
156- return await this . perform ( command ) as proto . ResponseListItems ;
167+ return this . command < proto . ResponseListItems > ( command ) ;
157168}
158169
159170async referenceItems ( command :proto . CommandReferenceItems ) :Promise < proto . ResponseReferenceItems > {
160- return await this . perform ( command ) as proto . ResponseReferenceItems ;
171+ return this . command < proto . ResponseReferenceItems > ( command ) ;
161172}
162173
163174async queryInterval ( command :proto . CommandQueryInterval ) :Promise < proto . ResponseQueryInterval > {
164- return await this . perform ( command ) as proto . ResponseQueryInterval ;
175+ return this . command < proto . ResponseQueryInterval > ( command ) ;
165176}
166177
167178async getSimulationStatus ( command :proto . CommandGetSimulationStatus ) :Promise < proto . ResponseGetSimulationStatus > {
168- return await this . perform ( command ) as proto . ResponseGetSimulationStatus ;
179+ return this . command < proto . ResponseGetSimulationStatus > ( command ) ;
169180}
170181
171182async runSimulation ( command :proto . CommandRunSimulation ) :Promise < proto . ResponseRunSimulation > {
172- return await this . perform ( command ) as proto . ResponseRunSimulation ;
183+ return this . command < proto . ResponseRunSimulation > ( command ) ;
173184}
174185
175186async pauseSimulation ( command :proto . CommandPauseSimulation ) :Promise < proto . ResponsePauseSimulation > {
176- return await this . perform ( command ) as proto . ResponsePauseSimulation ;
187+ return this . command < proto . ResponsePauseSimulation > ( command ) ;
177188}
178189}