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 @@ -Brain Exercise App logo +Brain Exercise App logo # 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/) -The BEAPP brain character with four skill areas +The BEAPP brain character with four skill areas ## 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'); +});