Enums in JavaScript

Our enum type ServerState has an underlying integer type. The possible values for ServerState are defined as constants. By implementing the toString method, values of ServerState can be printed out or converted to strings.

const ServerState = Object.freeze({
    IDLE: 0,
    CONNECTED: 1,
    ERROR: 2,
    RETRYING: 3
});

const stateName = {
    [ServerState.IDLE]: 'idle',
    [ServerState.CONNECTED]: 'connected',
    [ServerState.ERROR]: 'error',
    [ServerState.RETRYING]: 'retrying',
};

function toString(ss) {
    return stateName[ss];
}

function transition(s) {
    switch (s) {
        case ServerState.IDLE:
            return ServerState.CONNECTED;
        case ServerState.CONNECTED:
        case ServerState.RETRYING:
            return ServerState.IDLE;
        case ServerState.ERROR:
            return ServerState.ERROR;
        default:
            throw new Error(`unknown state: ${s}`);
    }
}

function main() {
    let ns = transition(ServerState.IDLE);
    console.log(toString(ns));

    let ns2 = transition(ns);
    console.log(toString(ns2));
}

main();

To run the program, save the code in a JavaScript file (for example, enum_example.js) and run it using Node.js:

$ node enum_example.js
connected
idle

This example demonstrates how to implement and use an enum-like pattern in JavaScript, including type safety and state transition mechanisms.