Skip to content

Commit 8e53057

Browse files
committed
generate documentation
1 parent 725a0a4 commit 8e53057

14 files changed

Lines changed: 758 additions & 31 deletions

File tree

README.md

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,77 @@
11
# LightMill
22

3-
LightMill is a framework used to manage, run and log user experiments.
3+
LightMill is a TypeScript monorepo for building, running, and logging user
4+
experiments.
5+
6+
It is organized as small focused packages that can be used independently or as
7+
a full stack:
8+
9+
1. Design generation and iteration.
10+
2. Timeline execution.
11+
3. React rendering helpers.
12+
4. Logging API contract, client, and server.
13+
14+
## Packages
15+
16+
| Package | Description | README |
17+
| ------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------ |
18+
| `@lightmill/convert-touchstone` | Convert TouchStone XML to Lightmill static design format. | [packages/convert-touchstone/README.md](packages/convert-touchstone/README.md) |
19+
| `@lightmill/static-design` | Model static experiment designs and start run iterators. | [packages/static-design/README.md](packages/static-design/README.md) |
20+
| `@lightmill/runner` | Execute timeline iterators with lifecycle callbacks. | [packages/runner/README.md](packages/runner/README.md) |
21+
| `@lightmill/react-experiment` | React `Run` component and hooks for task execution/logging. | [packages/react-experiment/README.md](packages/react-experiment/README.md) |
22+
| `@lightmill/log-api` | Shared API contract and OpenAPI artifacts for logging. | [packages/log-api/README.md](packages/log-api/README.md) |
23+
| `@lightmill/log-client` | Browser/client SDK for sessions, resumable runs, and logs. | [packages/log-client/README.md](packages/log-client/README.md) |
24+
| `@lightmill/log-server` | Express middleware and SQLite datastore for logs. | [packages/log-server/README.md](packages/log-server/README.md) |
25+
26+
## Quick Start
27+
28+
### Requirements
29+
30+
- Node.js 22.x
31+
- pnpm 10+
32+
33+
### Install dependencies
34+
35+
```sh
36+
pnpm install
37+
```
38+
39+
### Build all packages
40+
41+
```sh
42+
pnpm -r run build
43+
```
44+
45+
### Run tests
46+
47+
```sh
48+
pnpm -r run test
49+
```
50+
51+
## Typical Stack
52+
53+
Common integration flow:
54+
55+
1. Convert or define a design with `@lightmill/convert-touchstone` or `@lightmill/static-design`.
56+
2. Execute tasks with `@lightmill/runner` or `@lightmill/react-experiment`.
57+
3. Persist logs through `@lightmill/log-client` + `@lightmill/log-server`.
58+
4. Use `@lightmill/log-api` as source of truth for API schemas and types.
59+
60+
## Repository Layout
61+
62+
```txt
63+
packages/
64+
convert-touchstone/
65+
static-design/
66+
runner/
67+
react-experiment/
68+
log-api/
69+
log-client/
70+
log-server/
71+
```
72+
73+
## Development Notes
74+
75+
- Each package has its own `tsconfig`, test setup, and changelog.
76+
- Public package entrypoints are defined through each package `exports` field.
77+
- API-related packages (`log-api`, `log-client`, `log-server`) follow JSON:API media type conventions.
Lines changed: 80 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
# @lightmill/convert-touchstone
22

3-
Convert a touchstone XML design file as produced by [touchstone](https://www.lri.fr/%7Eappert/website/touchstone/touchstone.html)'s [design platform](https://github.com/jdfekete/touchstone-platforms/tree/master/design-platform) to a format that can be directly provided to [@lightmill/static-design](../static-design).
3+
Convert a TouchStone XML design file into a Lightmill static design object.
44

5-
## Install
5+
This package is useful when your experiment design is authored in TouchStone and
6+
you want to execute it with Lightmill packages such as
7+
[@lightmill/static-design](../static-design) and [@lightmill/runner](../runner).
68

7-
### NPM
9+
## Install
810

911
```sh
1012
npm install @lightmill/convert-touchstone
1113
```
1214

13-
Note: You might not need to install @lightmill/convert-touchstone, [`npx`](https://www.npmjs.com/package/npx) can be used to download and immediately run the program.
15+
You can also run it without installing through `npx`.
1416

1517
### Direct download
1618

17-
Download the latest version then, then in your html file:
19+
Download the latest version, then in your HTML file:
1820

1921
```html
2022
<script src="lightmill-convert-touchstone.js"></script>
@@ -24,49 +26,100 @@ The library will be injected in `lightmill.convertTouchstone`.
2426

2527
## Usage
2628

29+
### CLI
30+
2731
```sh
2832
lightmill-convert-touchstone <input-file>
2933
```
3034

31-
Or (if you do not need to install it and prefer to use `npx`):
35+
or:
3236

3337
```sh
3438
npx @lightmill/convert-touchstone <input-file>
3539
```
3640

37-
## API
41+
### JavaScript API
42+
43+
```ts
44+
import convertTouchstone from '@lightmill/convert-touchstone';
45+
46+
const design = await convertTouchstone(xml, {
47+
preRun: 'pre-run',
48+
trial: (trial) => ({ ...trial, type: 'trial' }),
49+
});
50+
```
51+
52+
## API Reference
53+
54+
### `convertTouchstone(touchStoneXML, options?)`
55+
56+
Parse TouchStone XML and return a Lightmill static design:
57+
58+
```ts
59+
Promise<{
60+
id: string;
61+
author: string;
62+
description: string;
63+
runs: Array<{ id: string; timeline: Array<{ id: string; type: string }> }>;
64+
}>
65+
```
66+
67+
Parameters:
68+
69+
| Param | Type | Description |
70+
| --------------- | ------------------------------------------ | ------------------------------------------------------------------ |
71+
| `touchStoneXML` | `string \| stream-like object with pipe()` | TouchStone XML content or stream. |
72+
| `options` | `object` | Mapper hooks used to inject tasks around runs, blocks, and trials. |
73+
74+
Supported mapper options:
75+
76+
| Option | Description |
77+
| ----------- | ---------------------------------------------------------------------------------- |
78+
| `preRun` | Add task(s) before each run timeline. |
79+
| `postRun` | Add task(s) after each run timeline. |
80+
| `preBlock` | Add task(s) before each block. |
81+
| `postBlock` | Add task(s) after each block. |
82+
| `trial` | Map each trial into one or more tasks. Defaults to a built-in `trial` task mapper. |
83+
84+
Mapper values can be:
85+
86+
1. A string task type.
87+
2. A task object.
88+
3. An array of string/task values.
89+
4. A function returning one of the above.
3890

39-
| Param | Type | Default | Description |
40-
| ------------------- | ----------------------------------------------------------------------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------- |
41-
| touchStoneXML | <code>String</code> \| <code>stream.Readable</code> | | The XML to parse. |
42-
| [options] | <code>object</code> | | Options |
43-
| [options.preBlock] | <code>string</code> \| <code>object</code> \| <code>array</code> \| <code>function</code> | | The type of the task to insert before each block or a function to map the block values to task(s). |
44-
| [options.postBlock] | <code>string</code> \| <code>object</code> \| <code>array</code> \| <code>function</code> | | The type of the task to insert after each block or a function to map the block values to task(s). |
45-
| [options.preRun] | <code>string</code> \| <code>object</code> \| <code>array</code> \| <code>function</code> | | The type of the task to insert before each run or a function to map the run values to task(s). |
46-
| [options.postRun] | <code>string</code> \| <code>object</code> \| <code>array</code> \| <code>function</code> | | The type of the task to insert after each run or a function to map the run values to task(s). |
47-
| [options.trial] | <code>string</code> \| <code>object</code> \| <code>array</code> \| <code>function</code> | <code>&quot;trial&quot;</code> | The type of the task to insert for each trial or a function to map the trial values to task(s). |
91+
When a task does not provide `id`, the converter generates one.
4892

4993
## Example
5094

5195
```js
52-
// Map each run to a task to insert before the trials of the run.
96+
import convertTouchstone from '@lightmill/convert-touchstone';
97+
98+
// Map each run to a task inserted before run trials.
5399
const preRun = (run, experiment) => ({
54100
...run,
55-
type: 'pre-run'
101+
type: 'pre-run',
56102
});
57-
// Mappers can also be strings...
58-
const postRun = 'post-run'; // This is the same as above.
59-
// ...arrays (if several tasks need to be inserted)...
103+
104+
// Mappers can also be strings.
105+
const postRun = 'post-run';
106+
107+
// ...arrays (if several tasks should be inserted)...
60108
const preBlock = [
61109
{ type: 'pre-block-1' },
62-
{ type: 'pre-block-2' }
110+
{ type: 'pre-block-2' },
63111
];
64-
// ...or functions that returns arrays.
112+
113+
// ...or functions returning arrays.
65114
const postBlock = (block, run, experiment) => [
66115
{ type: 'post-block-1', runId: run.id },
67-
{ ...block , type: 'post-block-2' }
68-
'post-block-2' // This is the same as above.
116+
{ ...block, type: 'post-block-2' },
69117
];
70-
convertTouchStone(data, { preBlock, postBlock, postRun, preRun })
71-
.then(doSomething);
118+
119+
const design = await convertTouchstone(xml, {
120+
preBlock,
121+
postBlock,
122+
preRun,
123+
postRun,
124+
});
72125
```

packages/log-api/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# @lightmill/log-api
2+
3+
Shared API contract for Lightmill logging endpoints.
4+
5+
This package exposes:
6+
7+
1. `openAPI`: generated OpenAPI document object.
8+
2. `routes`: route-level request/response schemas.
9+
3. JSON:API server error schemas from `server-errors`.
10+
4. `openapi.yaml` export for tooling/code generation.
11+
12+
## Install
13+
14+
```sh
15+
npm install @lightmill/log-api
16+
```
17+
18+
## Usage
19+
20+
### JavaScript/TypeScript
21+
22+
```ts
23+
import { openAPI, routes } from '@lightmill/log-api';
24+
25+
console.log(openAPI.info.title);
26+
console.log(Object.keys(routes));
27+
```
28+
29+
### OpenAPI file export
30+
31+
```ts
32+
import specPath from '@lightmill/log-api/openapi.yaml';
33+
```
34+
35+
Or via CLI tools:
36+
37+
```sh
38+
openapi-typescript node_modules/@lightmill/log-api/dist/openapi.yaml --output ./types.ts
39+
```
40+
41+
## API Reference
42+
43+
### `openAPI`
44+
45+
OpenAPI 3.1 document object generated from route schemas.
46+
47+
### `routes`
48+
49+
Map of route definitions keyed by path and method. Useful for server integration and type-safe handler validation.
50+
51+
### Re-exported error schemas
52+
53+
The package root re-exports `server-errors` members such as:
54+
55+
- `RequestValidationErrorResponse`
56+
- `NotFoundErrorResponse`
57+
- `InternalServerErrorResponse`
58+
- `MethodNotAllowedErrorResponse`
59+
- `UnsupportedMediaTypeErrorResponse`
60+
- `SessionRequiredErrorResponse`
61+
- `ServerErrorResponse`
62+
63+
These schemas are useful when validating server responses and documenting errors consistently.

packages/log-client/README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# @lightmill/log-client
2+
3+
Browser/client SDK for the Lightmill log server.
4+
5+
This package helps you:
6+
7+
1. Discover resumable runs for a participant session.
8+
2. Start or resume runs.
9+
3. Stream logs in-order and reliably flush before completion.
10+
11+
## Install
12+
13+
```sh
14+
npm install @lightmill/log-client
15+
```
16+
17+
## Usage
18+
19+
```ts
20+
import { Client } from '@lightmill/log-client';
21+
22+
type MyLog =
23+
| { type: 'trial-start'; trialId: string }
24+
| { type: 'trial-end'; trialId: string; durationMs: number };
25+
26+
const client = new Client<MyLog>({
27+
apiRoot: 'https://example.com/api',
28+
});
29+
30+
const logger = await client.startRun({
31+
experimentName: 'pointing-study',
32+
runName: 'participant-42',
33+
});
34+
35+
await logger.addLog({ type: 'trial-start', trialId: '1' });
36+
await logger.addLog({ type: 'trial-end', trialId: '1', durationMs: 812 });
37+
await logger.completeRun();
38+
```
39+
40+
## API Reference
41+
42+
### `class Client<Log>`
43+
44+
Exported as `Client` (implemented by `LightmillClient`).
45+
46+
| Method | Description |
47+
| -------------------------------------------------------------------- | ----------------------------------------------------------------- |
48+
| `new Client({ apiRoot, serializeLog? })` | Create a client bound to an API root. |
49+
| `getResumableRuns({ resumableLogTypes, experimentName?, runName? })` | Fetch current-session runs that can resume from a known log type. |
50+
| `startRun(options)` | Start a new run or resume an existing one, returns a logger. |
51+
| `logout()` | Delete current session on the server. |
52+
53+
### `Logger` type
54+
55+
Returned by `startRun(...)`.
56+
57+
Main operations:
58+
59+
- `addLog(log)`
60+
- `flush()`
61+
- `completeRun()`
62+
- `cancelRun()`
63+
- `interruptRun()`
64+
65+
## Notes
66+
67+
- Requests use JSON:API media type `application/vnd.api+json`.
68+
- For non-JSON-compatible values, provide a custom `serializeLog`.
69+
- `flush()` only waits for logs queued before it was called.

0 commit comments

Comments
 (0)