# Tutorial: building a package simulator with static-memorix

This example shows how to turn `@x12i/api-simulator` into a **full package
simulator**: domain logic + data + metadata, composed with
[`@x12i/static-memorix`](https://www.npmjs.com/package/@x12i/static-memorix)
for Memorix Explorer (`/api/explorer/*`) and Metadata (`/api/metadata/*`)
parity.

```text
examples/flowstate-simulator/
├─ TUTORIAL.md          <- you are here
├─ demo.mjs             <- run this first (no HTTP listen required)
├─ package.json
├─ mocks/               <- shared fixtures (data + metadata + packs)
│  ├─ data/product|users|memory|system/
│  ├─ metadata/         <- explorer lists, object-types, write-descriptors
│  └─ metadata-packs/   <- declarative packs for /api/metadata/*
└─ src/
   ├─ bridge.mjs        <- load mocks into api.data / createStore seeds
   ├─ data/seed.mjs
   ├─ state/board.mjs   <- mutable package board (createStore)
   ├─ simulations/board.mjs
   ├─ api.mjs           <- createApiSimulator package REST
   ├─ memorix.mjs       <- buildServer against MOCKS_DIR
   └─ server.mjs        <- one port: tryDispatch, else forward to memorix
```

## Mental model

| Concern | Who owns it |
|--------|-------------|
| Package REST (`/api/v1/flowstate/*`) | `@x12i/api-simulator` (this example) |
| Explorer + Metadata APIs | `@x12i/static-memorix` |
| Fixture JSON on disk | **Shared** `mocks/` (both read the same tree) |
| Package-only mutable state (pins, overlays) | `createStore` in `src/state/` |

`@x12i/api-simulator` itself does **not** load Memorix data or metadata. Your
package simulator does — by reading fixtures and/or composing static-memorix.

```text
Client
  │
  ▼
server.mjs  ──tryDispatch──▶  api-simulator  (package REST)
  │ miss
  └──inject─────────────────▶  static-memorix (explorer + metadata)
                                    │
                                    ▼
                              mocks/ (shared)
```

## 1. Prerequisites

From the **repo root**:

```bash
npm install
npm run build
npm install -w is not used for examples; install the example deps:
cd examples/flowstate-simulator && npm install && cd ../..
```

Or, with `@x12i/static-memorix` already available at the root (devDependency):

```bash
npm install
npm run build
node examples/flowstate-simulator/demo.mjs
```

## 2. Run the demo (no server)

```bash
node examples/flowstate-simulator/demo.mjs
```

You should see the bridge load product snapshots and metadata packs, package
REST health/catalog/board/pin steps, then static-memorix `/health`,
`/api/explorer/records/collection`, and `/api/metadata/abstracts` against the
**same** `mocks/` directory.

## 3. Shared mocks

static-memorix expects:

- `mocks/data/<objectType>/<contentType>.json`
- `mocks/metadata/**` (explorer metadata fixtures)
- `mocks/metadata-packs/*.json` (declarative packs for `/api/metadata/*`)

This example ships a curated FlowState subset (product + users + memory +
system + metadata + packs). To start from the full bundled demo instead:

```bash
npx @x12i/static-memorix create-demo --dir ./memorix-demo
# then point MOCKS_DIR at ./memorix-demo and adapt the bridge seeds
```

## 4. Bridge helpers

[`src/bridge.mjs`](src/bridge.mjs) is **example-local** (not a published
package). Copy it into your own `*-simulator` package if useful.

- `loadMemorixDataMocks(mocksDir)` → `{ product: { snapshots: [...] }, ... }`
- `loadMemorixMetadataPacks(mocksDir)` → `{ ops: {...}, ... }`
- `toStoreSeed(rows)` → rows with `id` for `createStore`

[`src/data/seed.mjs`](src/data/seed.mjs) wires those into package seeds.
[`src/state/board.mjs`](src/state/board.mjs) seeds `createStore` from the same
product snapshots so package REST and explorer start from one source of truth.

## 5. Package REST (`api.mjs`)

Three behaviors, same as the library demo:

1. **fixed** — `GET /api/v1/flowstate/health`
2. **relative** — `GET /api/v1/flowstate/catalog` (reads `data.metadataPackIds`)
3. **simulation** — `GET /board`, pin/status mutations over `boardStore`

This is the surface **your product** owns: summaries, workflows, and anything
that is not a stock Explorer/Metadata route.

## 6. Compose static-memorix

[`src/memorix.mjs`](src/memorix.mjs) sets `process.env.MOCKS_DIR` **before**
importing `@x12i/static-memorix` (config resolves on first load), then calls
`buildServer()`.

[`src/server.mjs`](src/server.mjs) is the single HTTP entry:

1. Parse the Node request into a simulator dispatch input.
2. `simulator.tryDispatch(...)` — if matched, return JSON.
3. Otherwise `memorix.inject(...)` and write the upstream status/body.

Start it:

```bash
node examples/flowstate-simulator/src/server.mjs
# http://127.0.0.1:5522
```

Try:

```bash
curl http://127.0.0.1:5522/api/v1/flowstate/health
curl http://127.0.0.1:5522/api/v1/flowstate/board
curl http://127.0.0.1:5522/api/explorer/records/collection?entityName=product&contentType=snapshots
curl -H "x-memorix-agent-ids: ops" http://127.0.0.1:5522/api/metadata/abstracts
```

## 7. Turn this into your own publishable package

Copy this folder into a new repo or workspace package, then:

1. Rename `flowstate-simulator` → `my-product-simulator`.
2. Replace `mocks/` with your fixtures (or `static-memorix create-demo`).
3. Keep or delete package REST endpoints under `src/simulations/` — add the
   logic your product needs on top of Memorix data.
4. Depend on `@x12i/api-simulator` and `@x12i/static-memorix`.
5. Export `createSimulator()` / `startServer()` from your package entry for
   tests and local CI.
6. Document `MOCKS_DIR`, ports, and which routes are package vs Memorix.

Checklist:

- [ ] Shared `mocks/data` + `mocks/metadata-packs`
- [ ] Bridge (or hand-written seeds) feeding `api.data` / `createStore`
- [ ] Package endpoints for product-specific behavior
- [ ] static-memorix for `/api/explorer/*` and `/api/metadata/*`
- [ ] One compose server (or two ports — also fine if you document them)
- [ ] A short tutorial or README in the package

## 8. What not to expect

static-memorix is a **local/CI mock**, not a substitute for full
`memorix-service` (relationships materialize/discover, Memory pulls,
pipelines, intelligence, abstract reverse-write). Package simulators that need
those stay on the real service for that slice.

## Related

- Library-only walkthrough (no Memorix): [`../library-demo/TUTORIAL.md`](../library-demo/TUTORIAL.md)
- Package pattern overview: [`../../docs/package-simulators.md`](../../docs/package-simulators.md)
- Engine README: [`../../README.md`](../../README.md)
