# Build and test layout

## Outputs

| Output | Contents |
|--------|----------|
| `dist/` | **ESM** (`"type": "module"` at package root) — primary publish surface |
| `dist-cjs/` | **CommonJS** + `dist-cjs/package.json` `{ "type": "commonjs" }` — `exports.require` |
| `.tests-out/` | Compiled **integration tests** (gitignored) |

`npm run build` runs **`scripts/clean-spurious-dist.js`** first so a stray **`dist/.tests/`** tree (from older local compiles) is removed and never published inside `dist/`.

## Why `.tests-out/` + ESM tests

Integration tests compile as **ESM** (`module: NodeNext`) and import **`../dist/index.js`** (the same ESM build consumers use). **`scripts/create-tests-package.js`** writes **`.tests-out/package.json`** with `{ "type": "module" }` so Node treats emitted `*.js` as ESM.

**Why not CJS tests + `dist-cjs`?** `@x12i/xronox-store`’s CJS build does `require('@x12i/xronox')`. Recent `@x12i/xronox` ships a **CJS `Proxy`** that can expose `createXronox` as a **Promise** until ESM finishes loading, which breaks `mod.createXronox()` inside the store. The **ESM** store path uses `import('@x12i/xronox')` and receives real exports — so tests must run on the ESM chain.

## Why not emit tests under `dist/.tests/`?

Emitting next to `dist/` would break relative imports (`../index.js` would not resolve cleanly from `dist/.tests/`). **`.tests-out/`** sits beside `dist/` at the package root so **`import '../dist/index.js'`** resolves correctly.

## Scripts (from `package.json`)

- `npm run build` — `tsc` (ESM) + `tsc -p tsconfig.cjs.json` + `create-cjs-package.js`
- `npm run build:tests` — compile `.tests/*.ts` + write `.tests-out/package.json`
- `npm test` / `test:patch` / `test:stale` / **`test:gaps`** / **`test:spy`** — build, then `node .tests-out/<file>.js`
- **`npm run test:all`** — runs all five integration scripts in sequence

Extra collections: **`activitix-gaps.test.ts`** uses `activitix-test-gaps`, `activitix-test-stale-count`; **`activitix-spy.test.ts`** uses `activitix-test-spy` (keep isolated like other `activitix-test-*` names).

## Prerequisites for `npm test`

- MongoDB reachable from env (see `.env.example`)
- **`.env` at monorepo root** (preferred): tests run from **`packages/activix/.tests-out/`**, so they resolve **`../.env`** → package `.env`, **`../../../.env`** → monorepo root `.env`.
- Successful `npm install` from npmjs (with auth for private `@x12i/*` deps)
