Modern interactive web applications aim to provide a highly responsive user experience by minimising the communication latency between clients and servers. Whilst the HTTP request-response model is sufficient for retrieving static assets, applying the same stateless communication approach for interactive use cases (such as real-time multiplayer games) introduces undesirable performance overhead. Developers have since adopted other communication transport abstractions over HTTP connections such as the WebSockets protocol  to enjoy low-latency full-duplex client-server communication in their applications over a single persistent connection. Enabling more complex communication patterns caters for more interactive use cases, but introduces additional correctness concerns to the developer.
Whilst WebSockets make this web-based implementation possible, they introduce the developer to a new family of communication errors, even for this simple game. In addition to the usual testing for game logic correctness, the developer needs to test against deadlocks (e.g. both players waiting for each other to make a move at the same time) and communication mismatches (e.g. player 1 sending a boolean to the game server instead of the board coordinates). The complexity of these errors correlates to the complexity of the required tests and scales with the complexity of communication patterns involved.
Multiparty Session Types (MPST)  provide a framework for formally specifying a structured communication pattern between concurrent processes and verifying implementations for correctness with respect to the communications aspect. By specifying the client-server interactions of our game as an MPST protocol and verifying the implementations against the protocol for conformance, MPST theory guarantees well-formed implementations to be free from communication errors.
We see the application of the MPST methodology to generating interactive TypeScript web applications to be an interesting design space — to what extent can the MPST methodology be applied to deliver a workflow where developers use the generated TypeScript APIs in their application to guarantee protocol conformance by construction? Such a workflow would ultimately decrease the overhead for incorporating MPST into mainstream web development, which reduces development time by programmatically verifying communication correctness of the implementation.
This paper presents a workflow for developing type-safe interactive SPAs motivated by the MPST framework: (1) An endpoint API code generation workflow targeting TypeScript-based web applications for multiparty sessions; (2) An encoding of session types in server-side TypeScript that enforces static linearity; and (3) An encoding of session types in browser-side TypeScript using the React framework that guarantees affine usage of communication channels.
2 The Scribble Framework
Development begins with specifying the expected communications between participants as a global protocol in Scribble , a MPST-based protocol specification language and code generation toolchain. We specify the Noughts and Crosses game as a Scribble protocol in LABEL:lst:game. In the protocol, the role Svr stands for the Server, and the roles P1 and P2 stand for the two Players respectively.
3 Encoding Session Types in TypeScript
Developers can implement their application using APIs generated from the EFSM to guarantee correctness by construction. Our approach integrates the EFSM into the development workflow by encoding session types as TypeScript types. Communication over the WebSocket protocol introduces additional constraints: communication is always initiated in the front-end and driven by user interactions, whilst back-end roles can only accept connections. This motivates our design of encoding the session types differently for server (Section 3.1) and client (LABEL:section:browser) targets.
3.1 Server-Side API Generation
We refer to the Svr EFSM (Figure 1) as a running example in this section. For server-side targets, we encode EFSM states into TypeScript types and consider branching (receiving) and selection (sending) states separately. We assign TypeScript encodings of states to their state identifiers in the EFSM, providing syntactic sugar when referring to the successor state when encoding the current state. For any state in the EFSM, we refer to the TypeScript type alias of its encoding as . We outline the encoding below using examples from the Noughts and Crosses game (LABEL:lst:svr).
We consider a receiving state as a unary branching state for conciseness. A branching state is encoded as an object literal  (a record type), with each branch ( denoting set of all branches), corresponding to a member field. A branch expecting to receive a message labelled carrying payload of type with successor state is encoded as an member field named of function type . The developer implements a branching operation by passing callbacks for each branch, parameterised by the expected message payload type for that branch.
We consider a sending state as a unary selection state for conciseness. A selection state is encoded as a union type  of internal choice encodings: each internal choice ( denoting set of all choices), sending a message labelled carrying payload of type with successor state is encoded as a tuple type of [Labels.label, T, ]. The developer implements a selection operation by passing the selected label and payload to send in the message. We generate a string enum (named Labels) wrapping the labels in the protocol.