Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions API.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Utility API

Import with require('./planner.js'), or load planner.js as a normal
browser script and use window.BeappPractice.
Install with npm install beapp-practice-planner.
Import with require('beapp-practice-planner') or named ES module imports.
TypeScript declarations are included for both module formats.
For a normal browser script, load planner.js and use window.BeappPractice.

| Function | Input | Output |
| --- | --- | --- |
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 1.1.0

- Publish the existing utility as beapp-practice-planner on npm.
- Add ES module exports and TypeScript declarations.
- Include the API reference and practical guide in the package.
- Keep the npm archive limited to utility code and documentation.

## 1.0.0

- Short sessions and an optional seven-day CSV plan.
Expand Down
43 changes: 36 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<img src="assets/brand-logo.webp" alt="Brain Exercise App logo" width="44">
<img src="https://raw.githubusercontent.com/YanTM/beapp-practice-kit/main/assets/brand-logo.webp" alt="Brain Exercise App logo" width="44">

# BEAPP Practice Kit

A small companion for [Brain Exercise App](https://brainexerciseapp.com/).
Choose a short session, understand the exercise, and keep a note of your result.

**[Open the planner and journal](https://yantm.github.io/beapp-practice-kit/)**
· [Read the practical guide](guide.md)
· [Read the practical guide](https://github.com/YanTM/beapp-practice-kit/blob/main/guide.md)
· [Open BEAPP Daily Training](https://brainexerciseapp.com/daily-brain-training/)

<img src="assets/hero.webp" alt="The BEAPP brain character with four skill areas" width="420">
<img src="https://raw.githubusercontent.com/YanTM/beapp-practice-kit/main/assets/hero.webp" alt="The BEAPP brain character with four skill areas" width="420">

## Start in three steps

Expand Down Expand Up @@ -61,13 +61,22 @@ Results describe performance in specific tasks. This kit is a planning and
note-taking tool, not a medical assessment or a promise of changes in
everyday abilities. [How BEAPP results are calculated](https://brainexerciseapp.com/how-results-are-calculated/).

## JavaScript usage
## Use the npm package

**beapp-practice-planner** is the small JavaScript utility from this kit.
Use it to add session choices, exercise instructions, or CSV exports to your
own tool. The npm package includes code and documentation; the ready-to-use
planner and journal are available through the live link above.

```sh
npm install beapp-practice-planner
```

Node.js 20 or newer is required only for development and the utility API.
No Node.js installation is needed to open the browser kit.

```js
const { createSession, createWeek, resultsToCsv } = require('./planner.js');
const { createSession, createWeek, resultsToCsv } = require('beapp-practice-planner');
const session = createSession({ minutes: 5, focus: 'memory' });
console.log(session.tasks.map(task => task.name));
const week = createWeek({ startDate: '2026-10-06', minutes: 5, focus: 'mixed' });
Expand All @@ -77,7 +86,25 @@ const csv = resultsToCsv([{
}]);
```

API reference: [API.md](API.md).
ES modules and TypeScript can use named imports:

```js
import { createSession } from 'beapp-practice-planner';

const session = createSession({ minutes: 5, focus: 'mixed' });
for (const task of session.tasks) {
console.log(task.name, task.url, task.steps);
}
```

`createSession` picks one task for 2 minutes, two for 5 minutes, and up to
three for 8 minutes. A focused session cannot contain more tasks than are
available in that area. `offset` rotates the starting exercise.
`createWeek` returns seven suggestions; your tool decides when to show them.
`resultsToCsv` exports manually entered results in each exercise's own units.
The utility itself does not store entries, contact a server, or import app history.

API reference: [API.md](https://github.com/YanTM/beapp-practice-kit/blob/main/API.md).
Dates use YYYY-MM-DD; the seven-day schedule uses UTC calendar arithmetic.
CSV export quotes text and protects against spreadsheet formula interpretation.

Expand All @@ -96,4 +123,6 @@ There is no build step and no runtime dependency.

New utility code and documentation are MIT licensed.
BEAPP logos, mascot artwork, and skill icons have separate
[brand asset terms](assets/NOTICE.md).
[brand asset terms](https://github.com/YanTM/beapp-practice-kit/blob/main/assets/NOTICE.md).
Brand images are displayed from the public repository and are not bundled
in the npm package.
3 changes: 3 additions & 0 deletions index.d.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './index.js';
declare const planner: typeof import('./index.js');
export default planner;
39 changes: 39 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export type SkillArea = 'memory' | 'attention' | 'reaction' | 'thinking';
export type Focus = 'mixed' | SkillArea;
export type Minutes = 2 | 5 | 8;
export type TaskId = 'reaction' | 'number_memory' | 'stroop' | 'visual_memory'
| 'pattern_recognition' | 'visual_search' | 'choice_reaction' | 'mental_rotation';
export type ResultUnit = 'ms' | 'digits' | 'cells' | '% correct';
export interface Task {
readonly id: TaskId;
readonly name: string;
readonly area: SkillArea;
readonly path: string;
readonly url: string;
readonly unit: ResultUnit;
readonly label: string;
readonly min: number;
readonly max?: number;
readonly integer?: boolean;
readonly steps: readonly string[];
readonly tip: string;
readonly read: string;
}
export interface SessionOptions { minutes?: Minutes; focus?: Focus; offset?: number; }
export interface Session { minutes: Minutes; focus: Focus; tasks: Task[]; note: string; }
export interface WeekOptions { startDate: string; minutes?: Minutes; focus?: Focus; }
export interface Day extends Session { date: string; }
export interface ResultInput {
date: string; task: TaskId; value: number | string; condition: string; notes?: string;
}
export interface Result {
date: string; task: TaskId; value: number; unit: ResultUnit; condition: string; notes: string;
}
export const TASKS: readonly Task[];
export const AREAS: readonly Focus[];
export function getTask(id: TaskId): Task;
export function createSession(options?: SessionOptions): Session;
export function createWeek(options: WeekOptions): Day[];
export function validateResult(result: ResultInput): Result;
export function resultsToCsv(results: ResultInput[]): string;
export function weekToCsv(week: Day[]): string;
8 changes: 8 additions & 0 deletions index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import planner from './planner.js';

export const {
TASKS, AREAS, getTask, createSession, createWeek,
validateResult, resultsToCsv, weekToCsv
} = planner;

export default planner;
51 changes: 41 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,62 @@
{
"name": "beapp-practice-kit",
"version": "1.0.0",
"description": "An offline-friendly session planner and manual result journal for Brain Exercise App.",
"name": "beapp-practice-planner",
"version": "1.1.0",
"description": "Zero-dependency helpers for short Brain Exercise App sessions, exercise instructions, and manual result CSV exports.",
"main": "planner.js",
"scripts": {
"test": "node --test tests/*.test.cjs",
"check": "node --check planner.js && node --check app.js"
"check": "node --check planner.js && node --check app.js && node --check index.mjs"
},
"engines": {
"node": ">=20"
},
"license": "MIT",
"homepage": "https://yantm.github.io/beapp-practice-kit/",
"homepage": "https://brainexerciseapp.com/",
"repository": {
"type": "git",
"url": "https://github.com/YanTM/beapp-practice-kit.git"
},
"files": [
"planner.js",
"index.mjs",
"index.d.ts",
"index.d.mts",
"API.md",
"guide.md",
"README.md",
"LICENSE"
],
"keywords": [
"brainexerciseapp",
"practice",
"planner",
"brain-exercise-app",
"practice-planner",
"session-planning",
"csv",
"memory",
"attention"
]
"attention",
"reaction-time",
"typescript"
],
"module": "index.mjs",
"types": "index.d.ts",
"exports": {
".": {
"import": {
"types": "./index.d.mts",
"default": "./index.mjs"
},
"require": {
"types": "./index.d.ts",
"default": "./planner.js"
}
},
"./package.json": "./package.json"
},
"author": "Digital Development Lab",
"bugs": {
"url": "https://github.com/YanTM/beapp-practice-kit/issues"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
}
}
23 changes: 23 additions & 0 deletions tests/package.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const { test } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');

test('package entry points work for CommonJS and ES modules', async () => {
const common = require('beapp-practice-planner');
const esm = await import('beapp-practice-planner');
assert.equal(esm.default, common);
assert.equal(esm.createSession, common.createSession);
assert.equal(common.createSession({ minutes: 2, focus: 'memory' }).tasks.length, 1);
assert.equal(esm.createWeek({ startDate: '2026-12-29' })[6].date, '2027-01-04');
});
test('publication allowlist contains only the utility and documentation', () => {
const pkg = require('../package.json');
const allowed = ['planner.js', 'index.mjs', 'index.d.ts', 'index.d.mts',
'API.md', 'guide.md', 'README.md', 'LICENSE'];
assert.deepEqual(pkg.files.slice().sort(), allowed.slice().sort());
for (const file of allowed) assert.ok(fs.existsSync(path.join(__dirname, '..', file)));
assert.equal(pkg.dependencies, undefined);
assert.equal(pkg.publishConfig.registry, 'https://registry.npmjs.org/');
assert.equal(pkg.publishConfig.access, 'public');
});
Loading