From c9fc41bb66f4d784c15730ebc2d7cd756f9faff9 Mon Sep 17 00:00:00 2001
From: Yan Lunin <47182734+YanTM@users.noreply.github.com>
Date: Tue, 6 Oct 2026 18:32:14 +0500
Subject: [PATCH] Package practice planner for npm
---
API.md | 6 +++--
CHANGELOG.md | 7 ++++++
README.md | 43 +++++++++++++++++++++++++++++------
index.d.mts | 3 +++
index.d.ts | 39 ++++++++++++++++++++++++++++++++
index.mjs | 8 +++++++
package.json | 51 +++++++++++++++++++++++++++++++++---------
tests/package.test.cjs | 23 +++++++++++++++++++
8 files changed, 161 insertions(+), 19 deletions(-)
create mode 100644 index.d.mts
create mode 100644 index.d.ts
create mode 100644 index.mjs
create mode 100644 tests/package.test.cjs
diff --git a/API.md b/API.md
index 6c732d7..b8efe03 100644
--- a/API.md
+++ b/API.md
@@ -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 |
| --- | --- | --- |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e50cb7f..4d5a219 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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.
diff --git a/README.md b/README.md
index 66bb0eb..e7b0fd0 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-
+
# BEAPP Practice Kit
@@ -6,10 +6,10 @@ 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/)
-
+
## Start in three steps
@@ -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' });
@@ -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.
@@ -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.
diff --git a/index.d.mts b/index.d.mts
new file mode 100644
index 0000000..d944713
--- /dev/null
+++ b/index.d.mts
@@ -0,0 +1,3 @@
+export * from './index.js';
+declare const planner: typeof import('./index.js');
+export default planner;
diff --git a/index.d.ts b/index.d.ts
new file mode 100644
index 0000000..5dcb033
--- /dev/null
+++ b/index.d.ts
@@ -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;
diff --git a/index.mjs b/index.mjs
new file mode 100644
index 0000000..35e9f60
--- /dev/null
+++ b/index.mjs
@@ -0,0 +1,8 @@
+import planner from './planner.js';
+
+export const {
+ TASKS, AREAS, getTask, createSession, createWeek,
+ validateResult, resultsToCsv, weekToCsv
+} = planner;
+
+export default planner;
diff --git a/package.json b/package.json
index 5e1d592..c96e54a 100644
--- a/package.json
+++ b/package.json
@@ -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/"
+ }
}
diff --git a/tests/package.test.cjs b/tests/package.test.cjs
new file mode 100644
index 0000000..e45b198
--- /dev/null
+++ b/tests/package.test.cjs
@@ -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');
+});