learngraph 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -21
- package/README.md +83 -2
- package/dist/cjs/parsers/base.js +189 -0
- package/dist/cjs/parsers/base.js.map +1 -0
- package/dist/cjs/parsers/demo.js +159 -0
- package/dist/cjs/parsers/demo.js.map +1 -0
- package/dist/cjs/parsers/extractor.js +191 -0
- package/dist/cjs/parsers/extractor.js.map +1 -0
- package/dist/cjs/parsers/index.js +43 -4
- package/dist/cjs/parsers/index.js.map +1 -1
- package/dist/cjs/parsers/json.js +157 -0
- package/dist/cjs/parsers/json.js.map +1 -0
- package/dist/cjs/parsers/markdown.js +168 -0
- package/dist/cjs/parsers/markdown.js.map +1 -0
- package/dist/cjs/parsers/samples.js +139 -0
- package/dist/cjs/parsers/samples.js.map +1 -0
- package/dist/cjs/storage/base.js +231 -0
- package/dist/cjs/storage/base.js.map +1 -0
- package/dist/cjs/storage/errors.js +128 -0
- package/dist/cjs/storage/errors.js.map +1 -0
- package/dist/cjs/storage/index.js +92 -5
- package/dist/cjs/storage/index.js.map +1 -1
- package/dist/cjs/storage/levelgraph.js +855 -0
- package/dist/cjs/storage/levelgraph.js.map +1 -0
- package/dist/cjs/storage/memory.js +447 -0
- package/dist/cjs/storage/memory.js.map +1 -0
- package/dist/cjs/storage/neo4j.js +866 -0
- package/dist/cjs/storage/neo4j.js.map +1 -0
- package/dist/cjs/storage/seeds.js +565 -0
- package/dist/cjs/storage/seeds.js.map +1 -0
- package/dist/cjs/types/parser.js +8 -0
- package/dist/cjs/types/parser.js.map +1 -0
- package/dist/esm/parsers/base.js +179 -0
- package/dist/esm/parsers/base.js.map +1 -0
- package/dist/esm/parsers/demo.js +154 -0
- package/dist/esm/parsers/demo.js.map +1 -0
- package/dist/esm/parsers/extractor.js +187 -0
- package/dist/esm/parsers/extractor.js.map +1 -0
- package/dist/esm/parsers/index.js +24 -5
- package/dist/esm/parsers/index.js.map +1 -1
- package/dist/esm/parsers/json.js +153 -0
- package/dist/esm/parsers/json.js.map +1 -0
- package/dist/esm/parsers/markdown.js +164 -0
- package/dist/esm/parsers/markdown.js.map +1 -0
- package/dist/esm/parsers/samples.js +136 -0
- package/dist/esm/parsers/samples.js.map +1 -0
- package/dist/esm/storage/base.js +221 -0
- package/dist/esm/storage/base.js.map +1 -0
- package/dist/esm/storage/errors.js +116 -0
- package/dist/esm/storage/errors.js.map +1 -0
- package/dist/esm/storage/index.js +71 -6
- package/dist/esm/storage/index.js.map +1 -1
- package/dist/esm/storage/levelgraph.js +818 -0
- package/dist/esm/storage/levelgraph.js.map +1 -0
- package/dist/esm/storage/memory.js +443 -0
- package/dist/esm/storage/memory.js.map +1 -0
- package/dist/esm/storage/neo4j.js +829 -0
- package/dist/esm/storage/neo4j.js.map +1 -0
- package/dist/esm/storage/seeds.js +561 -0
- package/dist/esm/storage/seeds.js.map +1 -0
- package/dist/esm/types/parser.js +7 -0
- package/dist/esm/types/parser.js.map +1 -0
- package/dist/types/parsers/base.d.ts +39 -0
- package/dist/types/parsers/base.d.ts.map +1 -0
- package/dist/types/parsers/demo.d.ts +87 -0
- package/dist/types/parsers/demo.d.ts.map +1 -0
- package/dist/types/parsers/extractor.d.ts +43 -0
- package/dist/types/parsers/extractor.d.ts.map +1 -0
- package/dist/types/parsers/index.d.ts +10 -0
- package/dist/types/parsers/index.d.ts.map +1 -1
- package/dist/types/parsers/json.d.ts +71 -0
- package/dist/types/parsers/json.d.ts.map +1 -0
- package/dist/types/parsers/markdown.d.ts +43 -0
- package/dist/types/parsers/markdown.d.ts.map +1 -0
- package/dist/types/parsers/samples.d.ts +27 -0
- package/dist/types/parsers/samples.d.ts.map +1 -0
- package/dist/types/storage/base.d.ts +39 -0
- package/dist/types/storage/base.d.ts.map +1 -0
- package/dist/types/storage/errors.d.ts +74 -0
- package/dist/types/storage/errors.d.ts.map +1 -0
- package/dist/types/storage/index.d.ts +50 -2
- package/dist/types/storage/index.d.ts.map +1 -1
- package/dist/types/storage/levelgraph.d.ts +92 -0
- package/dist/types/storage/levelgraph.d.ts.map +1 -0
- package/dist/types/storage/memory.d.ts +70 -0
- package/dist/types/storage/memory.d.ts.map +1 -0
- package/dist/types/storage/neo4j.d.ts +88 -0
- package/dist/types/storage/neo4j.d.ts.map +1 -0
- package/dist/types/storage/seeds.d.ts +27 -0
- package/dist/types/storage/seeds.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +1 -0
- package/dist/types/types/index.d.ts.map +1 -1
- package/dist/types/types/parser.d.ts +208 -0
- package/dist/types/types/parser.d.ts.map +1 -0
- package/package.json +4 -2
- package/scripts/postinstall.js +68 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Sample syllabi for testing and demonstration
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.SAMPLE_SYLLABI = exports.PROGRAMMING_101_SYLLABUS = exports.KINDERGARTEN_MATH_SYLLABUS = exports.PHYSICS_101_SYLLABUS = void 0;
|
|
9
|
+
/**
|
|
10
|
+
* Sample physics syllabus (university level)
|
|
11
|
+
*/
|
|
12
|
+
exports.PHYSICS_101_SYLLABUS = `# Introduction to Physics
|
|
13
|
+
|
|
14
|
+
## Course Information
|
|
15
|
+
PHYS 101 - Introduction to Physics
|
|
16
|
+
Fall Semester
|
|
17
|
+
|
|
18
|
+
## Week 1: Motion and Kinematics
|
|
19
|
+
|
|
20
|
+
### Learning Objectives
|
|
21
|
+
- Define position, displacement, velocity, and acceleration
|
|
22
|
+
- Calculate average and instantaneous velocity from position data
|
|
23
|
+
- Apply kinematic equations to solve motion problems in one dimension
|
|
24
|
+
- Analyze position-time and velocity-time graphs
|
|
25
|
+
|
|
26
|
+
## Week 2: Forces and Newton's Laws
|
|
27
|
+
|
|
28
|
+
### Learning Objectives
|
|
29
|
+
- Identify all forces acting on an object using free-body diagrams
|
|
30
|
+
- Apply Newton's First Law to explain equilibrium conditions
|
|
31
|
+
- Calculate net force and acceleration using Newton's Second Law
|
|
32
|
+
- Analyze action-reaction pairs using Newton's Third Law
|
|
33
|
+
|
|
34
|
+
## Week 3: Work and Energy
|
|
35
|
+
|
|
36
|
+
### Learning Objectives
|
|
37
|
+
- Calculate work done by constant and variable forces
|
|
38
|
+
- Apply the work-energy theorem to solve problems
|
|
39
|
+
- Distinguish between kinetic and potential energy
|
|
40
|
+
- Analyze systems using conservation of energy
|
|
41
|
+
|
|
42
|
+
## Week 4: Momentum and Collisions
|
|
43
|
+
|
|
44
|
+
### Learning Objectives
|
|
45
|
+
- Calculate linear momentum of objects and systems
|
|
46
|
+
- Apply impulse-momentum theorem to analyze collisions
|
|
47
|
+
- Distinguish between elastic and inelastic collisions
|
|
48
|
+
- Solve collision problems using conservation of momentum
|
|
49
|
+
`;
|
|
50
|
+
/**
|
|
51
|
+
* Sample kindergarten math syllabus
|
|
52
|
+
*/
|
|
53
|
+
exports.KINDERGARTEN_MATH_SYLLABUS = `# Kindergarten Mathematics
|
|
54
|
+
|
|
55
|
+
## Course Information
|
|
56
|
+
Grade: Kindergarten
|
|
57
|
+
Subject: Mathematics
|
|
58
|
+
|
|
59
|
+
## Unit 1: Counting and Cardinality
|
|
60
|
+
|
|
61
|
+
### Learning Objectives
|
|
62
|
+
- Count objects from 1 to 20
|
|
63
|
+
- Recognize and write number symbols 0-20
|
|
64
|
+
- Compare groups using words: more, less, same
|
|
65
|
+
- Understand that the last number counted tells how many
|
|
66
|
+
|
|
67
|
+
## Unit 2: Number Operations
|
|
68
|
+
|
|
69
|
+
### Learning Objectives
|
|
70
|
+
- Understand addition as putting together
|
|
71
|
+
- Understand subtraction as taking apart
|
|
72
|
+
- Represent addition and subtraction with objects
|
|
73
|
+
- Solve simple addition problems within 10
|
|
74
|
+
|
|
75
|
+
## Unit 3: Shapes and Geometry
|
|
76
|
+
|
|
77
|
+
### Learning Objectives
|
|
78
|
+
- Identify circles, squares, triangles, and rectangles
|
|
79
|
+
- Describe shapes using words like sides and corners
|
|
80
|
+
- Compare shapes by size and orientation
|
|
81
|
+
- Create pictures using basic shapes
|
|
82
|
+
|
|
83
|
+
## Unit 4: Measurement
|
|
84
|
+
|
|
85
|
+
### Learning Objectives
|
|
86
|
+
- Compare objects by length (longer, shorter)
|
|
87
|
+
- Compare objects by weight (heavier, lighter)
|
|
88
|
+
- Sort objects by size, color, or shape
|
|
89
|
+
- Describe position using words: above, below, beside
|
|
90
|
+
`;
|
|
91
|
+
/**
|
|
92
|
+
* Sample programming course syllabus
|
|
93
|
+
*/
|
|
94
|
+
exports.PROGRAMMING_101_SYLLABUS = `# Introduction to Programming
|
|
95
|
+
|
|
96
|
+
## Course Information
|
|
97
|
+
CS 101 - Introduction to Programming with Python
|
|
98
|
+
|
|
99
|
+
## Module 1: Getting Started
|
|
100
|
+
|
|
101
|
+
### Learning Objectives
|
|
102
|
+
- Install and configure Python development environment
|
|
103
|
+
- Write and execute a simple Python program
|
|
104
|
+
- Identify syntax errors in Python code
|
|
105
|
+
- Use print statements to display output
|
|
106
|
+
|
|
107
|
+
## Module 2: Variables and Data Types
|
|
108
|
+
|
|
109
|
+
### Learning Objectives
|
|
110
|
+
- Define variables and assign values
|
|
111
|
+
- Distinguish between integers, floats, and strings
|
|
112
|
+
- Apply type conversion between data types
|
|
113
|
+
- Calculate results using arithmetic operators
|
|
114
|
+
|
|
115
|
+
## Module 3: Control Flow
|
|
116
|
+
|
|
117
|
+
### Learning Objectives
|
|
118
|
+
- Write conditional statements using if-else
|
|
119
|
+
- Evaluate boolean expressions
|
|
120
|
+
- Create loops using for and while statements
|
|
121
|
+
- Design nested control structures
|
|
122
|
+
|
|
123
|
+
## Module 4: Functions
|
|
124
|
+
|
|
125
|
+
### Learning Objectives
|
|
126
|
+
- Define functions with parameters
|
|
127
|
+
- Apply return values from functions
|
|
128
|
+
- Design functions that call other functions
|
|
129
|
+
- Analyze scope and local variables
|
|
130
|
+
`;
|
|
131
|
+
/**
|
|
132
|
+
* All sample syllabi
|
|
133
|
+
*/
|
|
134
|
+
exports.SAMPLE_SYLLABI = {
|
|
135
|
+
physics: exports.PHYSICS_101_SYLLABUS,
|
|
136
|
+
kindergarten: exports.KINDERGARTEN_MATH_SYLLABUS,
|
|
137
|
+
programming: exports.PROGRAMMING_101_SYLLABUS,
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=samples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"samples.js","sourceRoot":"","sources":["../../../src/parsers/samples.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH;;GAEG;AACU,QAAA,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCnC,CAAC;AAEF;;GAEG;AACU,QAAA,0BAA0B,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCzC,CAAC;AAEF;;GAEG;AACU,QAAA,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCvC,CAAC;AAEF;;GAEG;AACU,QAAA,cAAc,GAAG;IAC5B,OAAO,EAAE,4BAAoB;IAC7B,YAAY,EAAE,kCAA0B;IACxC,WAAW,EAAE,gCAAwB;CAC7B,CAAC"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Base class and utilities for storage adapters
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.generateId = generateId;
|
|
9
|
+
exports.nowISO = nowISO;
|
|
10
|
+
exports.inputToSkillNode = inputToSkillNode;
|
|
11
|
+
exports.inputToEdge = inputToEdge;
|
|
12
|
+
exports.validateSkillInput = validateSkillInput;
|
|
13
|
+
exports.validateEdgeInput = validateEdgeInput;
|
|
14
|
+
exports.requireConnection = requireConnection;
|
|
15
|
+
exports.calculateStats = calculateStats;
|
|
16
|
+
const index_js_1 = require("../types/index.js");
|
|
17
|
+
const errors_js_1 = require("./errors.js");
|
|
18
|
+
/**
|
|
19
|
+
* Generate a unique ID with optional prefix
|
|
20
|
+
*/
|
|
21
|
+
function generateId(prefix = '') {
|
|
22
|
+
const timestamp = Date.now().toString(36);
|
|
23
|
+
const random = Math.random().toString(36).substring(2, 10);
|
|
24
|
+
return prefix ? `${prefix}_${timestamp}${random}` : `${timestamp}${random}`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get current ISO timestamp
|
|
28
|
+
*/
|
|
29
|
+
function nowISO() {
|
|
30
|
+
return new Date().toISOString();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert SkillNodeInput to full SkillNode with generated fields
|
|
34
|
+
*/
|
|
35
|
+
function inputToSkillNode(input) {
|
|
36
|
+
const now = nowISO();
|
|
37
|
+
const node = {
|
|
38
|
+
id: input.id ?? (0, index_js_1.createSkillId)(generateId('skill')),
|
|
39
|
+
name: input.name,
|
|
40
|
+
description: input.description,
|
|
41
|
+
bloomLevel: input.bloomLevel,
|
|
42
|
+
difficulty: input.difficulty,
|
|
43
|
+
isThresholdConcept: input.isThresholdConcept,
|
|
44
|
+
masteryThreshold: input.masteryThreshold,
|
|
45
|
+
estimatedMinutes: input.estimatedMinutes,
|
|
46
|
+
tags: input.tags,
|
|
47
|
+
metadata: input.metadata,
|
|
48
|
+
createdAt: now,
|
|
49
|
+
updatedAt: now,
|
|
50
|
+
};
|
|
51
|
+
// Only add optional fields if they have values
|
|
52
|
+
if (input.standardAlignment !== undefined) {
|
|
53
|
+
node.standardAlignment = input.standardAlignment;
|
|
54
|
+
}
|
|
55
|
+
if (input.domain !== undefined) {
|
|
56
|
+
node.domain = input.domain;
|
|
57
|
+
}
|
|
58
|
+
if (input.gradeLevel !== undefined) {
|
|
59
|
+
node.gradeLevel = input.gradeLevel;
|
|
60
|
+
}
|
|
61
|
+
return node;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Convert PrerequisiteEdgeInput to full PrerequisiteEdge with generated fields
|
|
65
|
+
*/
|
|
66
|
+
function inputToEdge(input) {
|
|
67
|
+
const edge = {
|
|
68
|
+
id: input.id ?? (0, index_js_1.createEdgeId)(generateId('edge')),
|
|
69
|
+
sourceId: input.sourceId,
|
|
70
|
+
targetId: input.targetId,
|
|
71
|
+
strength: input.strength,
|
|
72
|
+
type: input.type,
|
|
73
|
+
metadata: input.metadata,
|
|
74
|
+
createdAt: nowISO(),
|
|
75
|
+
};
|
|
76
|
+
// Only add optional fields if they have values
|
|
77
|
+
if (input.reasoning !== undefined) {
|
|
78
|
+
edge.reasoning = input.reasoning;
|
|
79
|
+
}
|
|
80
|
+
return edge;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Validate skill input data
|
|
84
|
+
*/
|
|
85
|
+
function validateSkillInput(input) {
|
|
86
|
+
if (!input.name || input.name.trim().length === 0) {
|
|
87
|
+
throw new errors_js_1.ValidationError('Skill name is required', 'name');
|
|
88
|
+
}
|
|
89
|
+
if (input.difficulty < 0 || input.difficulty > 1) {
|
|
90
|
+
throw new errors_js_1.ValidationError('Difficulty must be between 0 and 1', 'difficulty', input.difficulty);
|
|
91
|
+
}
|
|
92
|
+
if (input.masteryThreshold < 0 || input.masteryThreshold > 1) {
|
|
93
|
+
throw new errors_js_1.ValidationError('Mastery threshold must be between 0 and 1', 'masteryThreshold', input.masteryThreshold);
|
|
94
|
+
}
|
|
95
|
+
if (input.estimatedMinutes < 0) {
|
|
96
|
+
throw new errors_js_1.ValidationError('Estimated minutes cannot be negative', 'estimatedMinutes', input.estimatedMinutes);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Validate edge input data
|
|
101
|
+
*/
|
|
102
|
+
function validateEdgeInput(input) {
|
|
103
|
+
if (!input.sourceId) {
|
|
104
|
+
throw new errors_js_1.ValidationError('Source skill ID is required', 'sourceId');
|
|
105
|
+
}
|
|
106
|
+
if (!input.targetId) {
|
|
107
|
+
throw new errors_js_1.ValidationError('Target skill ID is required', 'targetId');
|
|
108
|
+
}
|
|
109
|
+
if (input.sourceId === input.targetId) {
|
|
110
|
+
throw new errors_js_1.ValidationError('Edge cannot reference the same skill as source and target', 'sourceId', input.sourceId);
|
|
111
|
+
}
|
|
112
|
+
if (input.strength < 0 || input.strength > 1) {
|
|
113
|
+
throw new errors_js_1.ValidationError('Edge strength must be between 0 and 1', 'strength', input.strength);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Ensure adapter is connected before operations
|
|
118
|
+
*/
|
|
119
|
+
function requireConnection(connected) {
|
|
120
|
+
if (!connected) {
|
|
121
|
+
throw new errors_js_1.NotConnectedError();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Calculate graph statistics from nodes and edges
|
|
126
|
+
*/
|
|
127
|
+
function calculateStats(nodes, edges) {
|
|
128
|
+
const inDegree = new Map();
|
|
129
|
+
const outDegree = new Map();
|
|
130
|
+
// Initialize degree maps
|
|
131
|
+
for (const node of nodes) {
|
|
132
|
+
inDegree.set(node.id, 0);
|
|
133
|
+
outDegree.set(node.id, 0);
|
|
134
|
+
}
|
|
135
|
+
// Count degrees
|
|
136
|
+
for (const edge of edges) {
|
|
137
|
+
const source = edge.sourceId;
|
|
138
|
+
const target = edge.targetId;
|
|
139
|
+
outDegree.set(source, (outDegree.get(source) || 0) + 1);
|
|
140
|
+
inDegree.set(target, (inDegree.get(target) || 0) + 1);
|
|
141
|
+
}
|
|
142
|
+
// Count roots (no prerequisites / in-degree 0)
|
|
143
|
+
let rootCount = 0;
|
|
144
|
+
let leafCount = 0;
|
|
145
|
+
for (const node of nodes) {
|
|
146
|
+
if (inDegree.get(node.id) === 0)
|
|
147
|
+
rootCount++;
|
|
148
|
+
if (outDegree.get(node.id) === 0)
|
|
149
|
+
leafCount++;
|
|
150
|
+
}
|
|
151
|
+
// Calculate bloom distribution
|
|
152
|
+
const bloomDistribution = {
|
|
153
|
+
remember: 0,
|
|
154
|
+
understand: 0,
|
|
155
|
+
apply: 0,
|
|
156
|
+
analyze: 0,
|
|
157
|
+
evaluate: 0,
|
|
158
|
+
create: 0,
|
|
159
|
+
};
|
|
160
|
+
for (const node of nodes) {
|
|
161
|
+
bloomDistribution[node.bloomLevel] =
|
|
162
|
+
(bloomDistribution[node.bloomLevel] || 0) + 1;
|
|
163
|
+
}
|
|
164
|
+
// Calculate difficulty distribution
|
|
165
|
+
const difficultyDistribution = {
|
|
166
|
+
foundational: 0,
|
|
167
|
+
basic: 0,
|
|
168
|
+
intermediate: 0,
|
|
169
|
+
advanced: 0,
|
|
170
|
+
expert: 0,
|
|
171
|
+
};
|
|
172
|
+
for (const node of nodes) {
|
|
173
|
+
if (node.difficulty <= 0.2)
|
|
174
|
+
difficultyDistribution.foundational++;
|
|
175
|
+
else if (node.difficulty <= 0.4)
|
|
176
|
+
difficultyDistribution.basic++;
|
|
177
|
+
else if (node.difficulty <= 0.6)
|
|
178
|
+
difficultyDistribution.intermediate++;
|
|
179
|
+
else if (node.difficulty <= 0.8)
|
|
180
|
+
difficultyDistribution.advanced++;
|
|
181
|
+
else
|
|
182
|
+
difficultyDistribution.expert++;
|
|
183
|
+
}
|
|
184
|
+
// Calculate max depth via BFS from all roots
|
|
185
|
+
let maxDepth = 0;
|
|
186
|
+
const adjacency = new Map();
|
|
187
|
+
for (const edge of edges) {
|
|
188
|
+
const source = edge.sourceId;
|
|
189
|
+
const target = edge.targetId;
|
|
190
|
+
if (!adjacency.has(source))
|
|
191
|
+
adjacency.set(source, []);
|
|
192
|
+
adjacency.get(source).push(target);
|
|
193
|
+
}
|
|
194
|
+
function bfsMaxDepth(startId) {
|
|
195
|
+
const queue = [
|
|
196
|
+
{ id: startId, depth: 0 },
|
|
197
|
+
];
|
|
198
|
+
let max = 0;
|
|
199
|
+
while (queue.length > 0) {
|
|
200
|
+
const { id, depth } = queue.shift();
|
|
201
|
+
max = Math.max(max, depth);
|
|
202
|
+
const neighbors = adjacency.get(id) || [];
|
|
203
|
+
for (const neighbor of neighbors) {
|
|
204
|
+
queue.push({ id: neighbor, depth: depth + 1 });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return max;
|
|
208
|
+
}
|
|
209
|
+
// Find max depth from all root nodes
|
|
210
|
+
for (const node of nodes) {
|
|
211
|
+
if (inDegree.get(node.id) === 0) {
|
|
212
|
+
maxDepth = Math.max(maxDepth, bfsMaxDepth(node.id));
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Calculate averages
|
|
216
|
+
const totalInDegree = Array.from(inDegree.values()).reduce((a, b) => a + b, 0);
|
|
217
|
+
const totalOutDegree = Array.from(outDegree.values()).reduce((a, b) => a + b, 0);
|
|
218
|
+
return {
|
|
219
|
+
nodeCount: nodes.length,
|
|
220
|
+
edgeCount: edges.length,
|
|
221
|
+
thresholdConceptCount: nodes.filter((n) => n.isThresholdConcept).length,
|
|
222
|
+
rootNodeCount: rootCount,
|
|
223
|
+
leafNodeCount: leafCount,
|
|
224
|
+
maxDepth,
|
|
225
|
+
avgPrerequisites: nodes.length > 0 ? totalInDegree / nodes.length : 0,
|
|
226
|
+
avgDependents: nodes.length > 0 ? totalOutDegree / nodes.length : 0,
|
|
227
|
+
bloomDistribution,
|
|
228
|
+
difficultyDistribution,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/storage/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Storage-specific errors for LearnGraph
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.CycleDetectedError = exports.TimeoutError = exports.ValidationError = exports.ReferenceError = exports.DuplicateError = exports.NotFoundError = exports.NotConnectedError = exports.ConnectionError = exports.StorageError = void 0;
|
|
9
|
+
/**
|
|
10
|
+
* Base error class for storage operations
|
|
11
|
+
*/
|
|
12
|
+
class StorageError extends Error {
|
|
13
|
+
code;
|
|
14
|
+
cause;
|
|
15
|
+
constructor(message, code, cause) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.cause = cause;
|
|
19
|
+
this.name = 'StorageError';
|
|
20
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.StorageError = StorageError;
|
|
24
|
+
/**
|
|
25
|
+
* Thrown when connection to storage backend fails
|
|
26
|
+
*/
|
|
27
|
+
class ConnectionError extends StorageError {
|
|
28
|
+
constructor(message, cause) {
|
|
29
|
+
super(message, 'CONNECTION_ERROR', cause);
|
|
30
|
+
this.name = 'ConnectionError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.ConnectionError = ConnectionError;
|
|
34
|
+
/**
|
|
35
|
+
* Thrown when attempting operation without active connection
|
|
36
|
+
*/
|
|
37
|
+
class NotConnectedError extends StorageError {
|
|
38
|
+
constructor() {
|
|
39
|
+
super('Not connected to storage backend', 'NOT_CONNECTED');
|
|
40
|
+
this.name = 'NotConnectedError';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.NotConnectedError = NotConnectedError;
|
|
44
|
+
/**
|
|
45
|
+
* Thrown when a skill or edge is not found
|
|
46
|
+
*/
|
|
47
|
+
class NotFoundError extends StorageError {
|
|
48
|
+
entityType;
|
|
49
|
+
entityId;
|
|
50
|
+
constructor(entityType, entityId) {
|
|
51
|
+
super(`${entityType} not found: ${entityId}`, 'NOT_FOUND');
|
|
52
|
+
this.entityType = entityType;
|
|
53
|
+
this.entityId = entityId;
|
|
54
|
+
this.name = 'NotFoundError';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.NotFoundError = NotFoundError;
|
|
58
|
+
/**
|
|
59
|
+
* Thrown when attempting to create a duplicate entity
|
|
60
|
+
*/
|
|
61
|
+
class DuplicateError extends StorageError {
|
|
62
|
+
entityType;
|
|
63
|
+
entityId;
|
|
64
|
+
constructor(entityType, entityId) {
|
|
65
|
+
super(`${entityType} already exists: ${entityId}`, 'DUPLICATE');
|
|
66
|
+
this.entityType = entityType;
|
|
67
|
+
this.entityId = entityId;
|
|
68
|
+
this.name = 'DuplicateError';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.DuplicateError = DuplicateError;
|
|
72
|
+
/**
|
|
73
|
+
* Thrown when edge references non-existent skill
|
|
74
|
+
*/
|
|
75
|
+
class ReferenceError extends StorageError {
|
|
76
|
+
edgeId;
|
|
77
|
+
missingSkillId;
|
|
78
|
+
role;
|
|
79
|
+
constructor(edgeId, missingSkillId, role) {
|
|
80
|
+
super(`Edge ${edgeId} references non-existent ${role} skill: ${missingSkillId}`, 'REFERENCE_ERROR');
|
|
81
|
+
this.edgeId = edgeId;
|
|
82
|
+
this.missingSkillId = missingSkillId;
|
|
83
|
+
this.role = role;
|
|
84
|
+
this.name = 'ReferenceError';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.ReferenceError = ReferenceError;
|
|
88
|
+
/**
|
|
89
|
+
* Thrown when data validation fails
|
|
90
|
+
*/
|
|
91
|
+
class ValidationError extends StorageError {
|
|
92
|
+
field;
|
|
93
|
+
value;
|
|
94
|
+
constructor(message, field, value) {
|
|
95
|
+
super(message, 'VALIDATION_ERROR');
|
|
96
|
+
this.field = field;
|
|
97
|
+
this.value = value;
|
|
98
|
+
this.name = 'ValidationError';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.ValidationError = ValidationError;
|
|
102
|
+
/**
|
|
103
|
+
* Thrown when a query times out
|
|
104
|
+
*/
|
|
105
|
+
class TimeoutError extends StorageError {
|
|
106
|
+
operation;
|
|
107
|
+
timeoutMs;
|
|
108
|
+
constructor(operation, timeoutMs) {
|
|
109
|
+
super(`Operation "${operation}" timed out after ${timeoutMs}ms`, 'TIMEOUT');
|
|
110
|
+
this.operation = operation;
|
|
111
|
+
this.timeoutMs = timeoutMs;
|
|
112
|
+
this.name = 'TimeoutError';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.TimeoutError = TimeoutError;
|
|
116
|
+
/**
|
|
117
|
+
* Thrown when a cycle is detected in the graph
|
|
118
|
+
*/
|
|
119
|
+
class CycleDetectedError extends StorageError {
|
|
120
|
+
path;
|
|
121
|
+
constructor(path) {
|
|
122
|
+
super(`Cycle detected in graph: ${path.join(' -> ')}`, 'CYCLE_DETECTED');
|
|
123
|
+
this.path = path;
|
|
124
|
+
this.name = 'CycleDetectedError';
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.CycleDetectedError = CycleDetectedError;
|
|
128
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/storage/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,99 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Graph storage adapters
|
|
3
|
+
* Graph storage adapters for LearnGraph
|
|
4
|
+
*
|
|
5
|
+
* Provides a unified interface for storing skill graphs with multiple
|
|
6
|
+
* backend options:
|
|
7
|
+
* - **MemoryStorage**: In-memory storage for testing
|
|
8
|
+
* - **LevelGraphStorage**: Browser/local storage using triples
|
|
9
|
+
* - **Neo4jStorage**: Production graph database
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { MemoryStorage, Neo4jStorage, LevelGraphStorage } from 'learngraph/storage';
|
|
14
|
+
*
|
|
15
|
+
* // For testing
|
|
16
|
+
* const testStorage = new MemoryStorage();
|
|
17
|
+
* await testStorage.connect({ backend: 'memory' });
|
|
18
|
+
*
|
|
19
|
+
* // For browser/local development
|
|
20
|
+
* const localStorage = new LevelGraphStorage();
|
|
21
|
+
* await localStorage.connect({ backend: 'levelgraph', path: './my-graph' });
|
|
22
|
+
*
|
|
23
|
+
* // For production
|
|
24
|
+
* const prodStorage = new Neo4jStorage();
|
|
25
|
+
* await prodStorage.connect({
|
|
26
|
+
* backend: 'neo4j',
|
|
27
|
+
* uri: 'bolt://localhost:7687',
|
|
28
|
+
* username: 'neo4j',
|
|
29
|
+
* password: 'password',
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* // Same API for all!
|
|
33
|
+
* const skill = await storage.createSkill({ ... });
|
|
34
|
+
* const prereqs = await storage.getPrerequisitesOf(skill.id);
|
|
35
|
+
* ```
|
|
4
36
|
*
|
|
5
37
|
* @packageDocumentation
|
|
6
38
|
*/
|
|
7
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
//
|
|
11
|
-
//
|
|
40
|
+
exports.Neo4jStorage = exports.LevelGraphStorage = exports.MemoryStorage = exports.calculateStats = exports.validateEdgeInput = exports.validateSkillInput = exports.inputToEdge = exports.inputToSkillNode = exports.nowISO = exports.generateId = exports.CycleDetectedError = exports.TimeoutError = exports.ValidationError = exports.ReferenceError = exports.DuplicateError = exports.NotFoundError = exports.NotConnectedError = exports.ConnectionError = exports.StorageError = void 0;
|
|
41
|
+
exports.createStorage = createStorage;
|
|
42
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
43
|
+
// Storage Errors
|
|
44
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
45
|
+
var errors_js_1 = require("./errors.js");
|
|
46
|
+
Object.defineProperty(exports, "StorageError", { enumerable: true, get: function () { return errors_js_1.StorageError; } });
|
|
47
|
+
Object.defineProperty(exports, "ConnectionError", { enumerable: true, get: function () { return errors_js_1.ConnectionError; } });
|
|
48
|
+
Object.defineProperty(exports, "NotConnectedError", { enumerable: true, get: function () { return errors_js_1.NotConnectedError; } });
|
|
49
|
+
Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return errors_js_1.NotFoundError; } });
|
|
50
|
+
Object.defineProperty(exports, "DuplicateError", { enumerable: true, get: function () { return errors_js_1.DuplicateError; } });
|
|
51
|
+
Object.defineProperty(exports, "ReferenceError", { enumerable: true, get: function () { return errors_js_1.ReferenceError; } });
|
|
52
|
+
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_js_1.ValidationError; } });
|
|
53
|
+
Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return errors_js_1.TimeoutError; } });
|
|
54
|
+
Object.defineProperty(exports, "CycleDetectedError", { enumerable: true, get: function () { return errors_js_1.CycleDetectedError; } });
|
|
55
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
56
|
+
// Base Utilities
|
|
57
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
58
|
+
var base_js_1 = require("./base.js");
|
|
59
|
+
Object.defineProperty(exports, "generateId", { enumerable: true, get: function () { return base_js_1.generateId; } });
|
|
60
|
+
Object.defineProperty(exports, "nowISO", { enumerable: true, get: function () { return base_js_1.nowISO; } });
|
|
61
|
+
Object.defineProperty(exports, "inputToSkillNode", { enumerable: true, get: function () { return base_js_1.inputToSkillNode; } });
|
|
62
|
+
Object.defineProperty(exports, "inputToEdge", { enumerable: true, get: function () { return base_js_1.inputToEdge; } });
|
|
63
|
+
Object.defineProperty(exports, "validateSkillInput", { enumerable: true, get: function () { return base_js_1.validateSkillInput; } });
|
|
64
|
+
Object.defineProperty(exports, "validateEdgeInput", { enumerable: true, get: function () { return base_js_1.validateEdgeInput; } });
|
|
65
|
+
Object.defineProperty(exports, "calculateStats", { enumerable: true, get: function () { return base_js_1.calculateStats; } });
|
|
66
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
67
|
+
// Storage Adapters
|
|
68
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
69
|
+
var memory_js_1 = require("./memory.js");
|
|
70
|
+
Object.defineProperty(exports, "MemoryStorage", { enumerable: true, get: function () { return memory_js_1.MemoryStorage; } });
|
|
71
|
+
var levelgraph_js_1 = require("./levelgraph.js");
|
|
72
|
+
Object.defineProperty(exports, "LevelGraphStorage", { enumerable: true, get: function () { return levelgraph_js_1.LevelGraphStorage; } });
|
|
73
|
+
var neo4j_js_1 = require("./neo4j.js");
|
|
74
|
+
Object.defineProperty(exports, "Neo4jStorage", { enumerable: true, get: function () { return neo4j_js_1.Neo4jStorage; } });
|
|
75
|
+
const memory_js_2 = require("./memory.js");
|
|
76
|
+
const levelgraph_js_2 = require("./levelgraph.js");
|
|
77
|
+
const neo4j_js_2 = require("./neo4j.js");
|
|
78
|
+
/**
|
|
79
|
+
* Create a storage adapter based on configuration.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const storage = createStorage({ backend: 'memory' });
|
|
84
|
+
* await storage.connect({ backend: 'memory' });
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
function createStorage(config) {
|
|
88
|
+
switch (config.backend) {
|
|
89
|
+
case 'memory':
|
|
90
|
+
return new memory_js_2.MemoryStorage();
|
|
91
|
+
case 'levelgraph':
|
|
92
|
+
return new levelgraph_js_2.LevelGraphStorage();
|
|
93
|
+
case 'neo4j':
|
|
94
|
+
return new neo4j_js_2.Neo4jStorage();
|
|
95
|
+
default:
|
|
96
|
+
throw new Error(`Unknown storage backend: ${config.backend}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
12
99
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;;;AAsEH,sCAWC;AA/DD,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAChF,yCAUqB;AATnB,yGAAA,YAAY,OAAA;AACZ,4GAAA,eAAe,OAAA;AACf,8GAAA,iBAAiB,OAAA;AACjB,0GAAA,aAAa,OAAA;AACb,2GAAA,cAAc,OAAA;AACd,2GAAA,cAAc,OAAA;AACd,4GAAA,eAAe,OAAA;AACf,yGAAA,YAAY,OAAA;AACZ,+GAAA,kBAAkB,OAAA;AAGpB,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAChF,qCAQmB;AAPjB,qGAAA,UAAU,OAAA;AACV,iGAAA,MAAM,OAAA;AACN,2GAAA,gBAAgB,OAAA;AAChB,sGAAA,WAAW,OAAA;AACX,6GAAA,kBAAkB,OAAA;AAClB,4GAAA,iBAAiB,OAAA;AACjB,yGAAA,cAAc,OAAA;AAGhB,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAChF,yCAA4C;AAAnC,0GAAA,aAAa,OAAA;AACtB,iDAAoD;AAA3C,kHAAA,iBAAiB,OAAA;AAC1B,uCAA0C;AAAjC,wGAAA,YAAY,OAAA;AAMrB,2CAA4C;AAC5C,mDAAoD;AACpD,yCAA0C;AAE1C;;;;;;;;GAQG;AACH,SAAgB,aAAa,CAAC,MAAqB;IACjD,QAAQ,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,QAAQ;YACX,OAAO,IAAI,yBAAa,EAAE,CAAC;QAC7B,KAAK,YAAY;YACf,OAAO,IAAI,iCAAiB,EAAE,CAAC;QACjC,KAAK,OAAO;YACV,OAAO,IAAI,uBAAY,EAAE,CAAC;QAC5B;YACE,MAAM,IAAI,KAAK,CAAC,4BAA6B,MAAwB,CAAC,OAAO,EAAE,CAAC,CAAC;IACrF,CAAC;AACH,CAAC"}
|