Skip to content

Further Defining "Modes" And Near Term Roadmap #361

@jbolda

Description

@jbolda

Running Simulators

We are more directly defining the different ways to run simulators to help improve the use, communication, and API design. We have been working towards three main ways to run your simulator: standalone, programmatic, and harnessed.

Standalone

This is the easiest way to run a simulator. It is run through a bin file which can be executed directly through npx. Effectively this will be a CLI, but each simulator will define it's own. A few of our simulators have some level of this in place already, e.g. npx @simulacrum/auth0-simulator. A simulator may expect any type of config, and we want to enable setting these config values from a command line arg (among config files or env vars as well).

The foundation simulator will not have this by default. However, when you build a custom/new simulator on top, we want to enable wiring up a CLI as easy a possible.

Programmatic

If you have used the foundation simulator, this is your primary entry point. Import the function, add the options, and execute that as a script.

import { simulation } from "@simulacrum/foundation-simulator";

let app = simulation();
app.listen(9999, () => console.log(`foundation server started at http://localhost:9999`));

This provides a high level of control, but you lose out on some of the ergonomics. One has to build up the methods for running it; be it CLI or within a test framework. At Frontside, we have mostly built up simulators through this methods and provided custom setup to meet each clients use case. Make that setup a little more generic and you land into the last method: harness.

Harness

We have built custom versions of this for clients, and have begun the work to provide a proper API for it in #347. It is built with the expectation that you will be running multiple simulators, or possibly other scripts. The harness provides a way to define the entry points to your simulators, and then export an object that is available as a test rig, e.g. start up your simulator in a beforeAll/beforeEach in a test suite, or can be dropped into a helper to create a CLI for the whole harness, e.g. npm run sim --watch, which is great for local development. Think of this as a Kubernetes control plane in some ways.

Helpers And Enablement

Now you might see some overlap in uses and places where one might want to define configuration. I want to define my simulator and it's config once, and allow all entry points to make use of it. Additionally though, we tend to see "layers" in our simulators. The foundation simulator handles the base server and parts to handle the simulation data state. That can come with its own configuration expectation. The auth0 simulator, for example, builds on top of the foundation simulator but comes with its own configuration expectations needed for the JWT, etc.

Flexibility is important, but not without building blocks to quickly assemble or use a simulator. Separately, we have been building a configuration library, configliere. It is built around the idea of multiple, composable parsing configs; see env vars, process vars, and config files. Using this library, we can have each "level" define its own configuration expectations, and allow custom effort (or auth0 or github api simulators) to extend their configuration expectations.

Next Steps

We will work through the final parts of #347 to provide all three main use cases. Separately and possibly in parallel (especially if folks are interested in helping out!), we will look to pull in configliere in ~effectively all of our packages to begin to provide the composable configuration we have identified here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions