npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@noesis-edu/core

v0.2.0

Published

Noesis Core SDK - Portable, dependency-free, deterministic mastery-based learning engine

Readme

@noesis-edu/core

Noesis Core SDK - A portable, dependency-free learning engine for mastery-based education.

Status

v0.1.0 Complete - All core modules implemented and tested.

Features

  • Skill Graph: DAG-based skill representation with validation, cycle detection, and topological ordering
  • Bayesian Knowledge Tracing (BKT): Research-backed learner modeling with inspectable probability estimates
  • FSRS Memory Scheduling: Modern spaced repetition scheduling for optimal retention
  • Diagnostic Assessment: Cold-start placement through adaptive diagnostic testing
  • Transfer Testing: Near/far transfer test gating for verified skill mastery
  • Session Planning: Deterministic action planning with configurable policies
  • Event Replay: Full determinism for reproducible learning decisions

Installation

npm install @noesis-edu/core

Quick Start

import {
  createSkillGraph,
  createNoesisCoreEngine,
  type Skill,
  type PracticeEvent,
} from '@noesis-edu/core';

// 1. Define your skill graph
const skills: Skill[] = [
  { id: 'arithmetic', name: 'Basic Arithmetic', prerequisites: [] },
  { id: 'algebra', name: 'Algebra', prerequisites: ['arithmetic'] },
  { id: 'calculus', name: 'Calculus', prerequisites: ['algebra'] },
];

const graph = createSkillGraph(skills);

// Validate the graph
const validation = graph.validate();
if (!validation.valid) {
  console.error('Invalid skill graph:', validation.errors);
}

// 2. Create the core engine
const engine = createNoesisCoreEngine(graph);

// 3. Process learning events
const event: PracticeEvent = {
  id: 'evt-1',
  type: 'practice',
  learnerId: 'learner-1',
  sessionId: 'session-1',
  timestamp: Date.now(),
  skillId: 'arithmetic',
  itemId: 'item-1',
  correct: true,
  responseTimeMs: 5000,
};

engine.processEvent(event);

// 4. Get recommendations (using default config)
import { DEFAULT_SESSION_CONFIG } from '@noesis-edu/core';

const nextAction = engine.getNextAction('learner-1', DEFAULT_SESSION_CONFIG);

console.log('Next action:', nextAction);
// { type: 'practice', skillId: 'arithmetic', reason: '...', priority: 40 }

// 5. Check progress
const progress = engine.getLearnerProgress('learner-1');
console.log('Progress:', progress);
// { totalSkills: 3, masteredSkills: 0, learningSkills: 1, ... }

Session Configuration

The SDK provides DEFAULT_SESSION_CONFIG with sensible defaults:

import { DEFAULT_SESSION_CONFIG } from '@noesis-edu/core';

// Default values:
// {
//   maxDurationMinutes: 30,
//   targetItems: 20,
//   masteryThreshold: 0.85,
//   enforceSpacedRetrieval: true,
//   requireTransferTests: true,
// }

// Use directly
const action = engine.getNextAction(learnerId, DEFAULT_SESSION_CONFIG);

// Or customize
const customConfig = {
  ...DEFAULT_SESSION_CONFIG,
  targetItems: 10,
  masteryThreshold: 0.9,
};
const action = engine.getNextAction(learnerId, customConfig);

Core Concepts

The Irreducible Learning Loop

The SDK implements a research-backed learning loop:

  1. Explicit Skill Graph (DAG) - Skills with prerequisites and dependencies
  2. Diagnostic-First Entry - Assess learner's starting state
  3. Smallest Leverage Gap - Target highest-impact skill to learn next
  4. Error-Focused Training - Prioritize practice on errors
  5. Mandatory Spaced Retrieval - Enforce retrieval at optimal intervals
  6. Transfer Tests with Gating - Verify near/far transfer before progression
  7. Learner Model Update - Adjust probability estimates based on evidence
  8. Repeat

Determinism & Replay

All operations are deterministic - same inputs produce same outputs:

import { createDeterministicEngine } from '@noesis-edu/core';

// Create engine with deterministic clock and ID generator
const engine = createDeterministicEngine(graph, {}, startTime);

// Replay events to reproduce exact state
engine.replayEvents(eventLog);

Modules

| Module | Purpose | Status | |--------|---------|--------| | graph/ | Skill graph (DAG) representation | ✅ Implemented | | learner/ | BKT-style learner modeling | ✅ Implemented | | memory/ | FSRS spaced repetition scheduling | ✅ Implemented | | diagnostic/ | Cold-start diagnostic assessment | ✅ Implemented | | transfer/ | Near/far transfer test gating | ✅ Implemented | | planning/ | Session planning with gap targeting | ✅ Implemented | | engine/ | Unified engine with replay support | ✅ Implemented | | events/ | Canonical event schema + factories | ✅ Implemented |

API Reference

Skill Graph

import { createSkillGraph } from '@noesis-edu/core';

const graph = createSkillGraph(skills);

// Validation
const result = graph.validate(); // { valid: boolean, errors: [] }

// Traversal
const order = graph.getTopologicalOrder(); // ['arithmetic', 'algebra', ...]
const prereqs = graph.getAllPrerequisites('calculus'); // ['arithmetic', 'algebra']
const deps = graph.getDependents('arithmetic'); // ['algebra', 'calculus']

BKT Learner Model

import { createBKTEngine, DEFAULT_BKT_PARAMS } from '@noesis-edu/core';

const bkt = createBKTEngine({
  pInit: 0.3,   // Initial mastery probability
  pLearn: 0.1, // Learning rate
  pSlip: 0.1,  // Slip probability
  pGuess: 0.2, // Guess probability
});

const model = bkt.createModel('learner-1', graph);
const updated = bkt.updateModel(model, practiceEvent);
const mastery = bkt.getPMastery(updated, 'arithmetic'); // 0.69...

FSRS Memory Scheduler

import { createFSRSScheduler, calculateRetention } from '@noesis-edu/core';

const scheduler = createFSRSScheduler({
  requestedRetention: 0.9, // Target 90% retention
  maxInterval: 365,        // Max 1 year between reviews
});

const state = scheduler.createState('skill-1');
const updated = scheduler.scheduleReview(state, true, 3); // Good rating

// Get due skills
const due = scheduler.getDueSkills(allStates, Date.now());

// Calculate retention
const retention = calculateRetention(stability, elapsedDays);

Diagnostic Engine

import { createDiagnosticEngine } from '@noesis-edu/core';

const diagnostic = createDiagnosticEngine({
  minItemsPerSkill: 2,
  maxItemsPerSkill: 5,
  masteryThreshold: 0.7,
});

// Generate diagnostic test
const items = diagnostic.generateDiagnostic(graph, itemMappings, 20);

// Analyze results
const estimates = diagnostic.analyzeResults(graph, itemMappings, responses);

Transfer Gate

import { createTransferGate } from '@noesis-edu/core';

const gate = createTransferGate({
  requireNearTransfer: true,
  requireFarTransfer: false,
});

const isUnlocked = gate.isSkillUnlocked('algebra', testResults, tests);
const pending = gate.getPendingTests('algebra', testResults, tests);

Session Planner

import { createSessionPlanner, DEFAULT_SESSION_CONFIG } from '@noesis-edu/core';

const planner = createSessionPlanner();

// Get next action
const action = planner.getNextAction(model, graph, memoryStates, config);

// Plan full session
const session = planner.planSession(model, graph, memoryStates, {
  targetItems: 20,
  masteryThreshold: 0.85,
  enforceSpacedRetrieval: true,
});

Event Factories

import {
  createEventFactoryContext,
  createPracticeEvent,
  createDiagnosticEvent,
} from '@noesis-edu/core';

const ctx = createEventFactoryContext(
  () => Date.now(),    // clock
  () => crypto.randomUUID() // idGenerator
);

const event = createPracticeEvent(
  ctx, 'learner-1', 'session-1', 'skill-1', 'item-1',
  true, 5000
);

Design Principles

  • No external dependencies - Pure TypeScript, runs anywhere
  • Deterministic - All decisions can be replayed from events
  • Inspectable - All internal state can be examined
  • Research-based - Implements BKT and FSRS algorithms

Determinism Guarantee

The core engine is fully deterministic: given the same inputs, it produces the same outputs every time. This enables:

  • Replay: Reproduce any past learning session by replaying events
  • Testing: Write predictable unit tests with known outcomes
  • Debugging: Compare engine states between runs

How It Works

All non-deterministic sources (timestamps, IDs) are injected rather than called directly:

// For deterministic operation (testing, replay):
const engine = createDeterministicEngine(graph, config, startTime);

// For production (uses Date.now() and UUID):
const engine = createNoesisCoreEngine(graph, config);

The defaults (Date.now(), Math.random()) are only used in factory functions and can always be overridden.

Development

Build

# From repo root
npm run build:core

# From packages/core
npm run build

Test

# From repo root
npm run test:core

# From packages/core - smoke test
npm run smoke

Smoke Test

The smoke test validates the public API works correctly:

npm run smoke:core

Expected output:

🔬 Running @noesis-edu/core smoke test (v0.1.0)

  ✓ Create a skill graph with 3 skills
  ✓ Create engine and learner model
  ✓ Process practice events and update model
  ✓ Get next action from session planner
  ✓ Deterministic replay produces identical results
  ✓ Export and import state for persistence

✅ All smoke tests passed! (6/6)

What Core Does NOT Include

These belong in adapters or apps, not core:

  • React/UI components → @noesis/sdk-web, apps/web-demo
  • Express/HTTP routes → apps/server
  • Database/ORM → apps/server
  • Attention tracking → @noesis/adapters-attention-web
  • LLM integration → @noesis/adapters-llm
  • Browser APIs → Adapters

Contributing

See the Core SDK Constitution for the canonical interface definitions.

License

MIT