learngraph 0.1.1 → 0.3.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.
Files changed (150) hide show
  1. package/LICENSE +190 -21
  2. package/README.md +165 -3
  3. package/dist/cjs/llm/adapters/anthropic.js +124 -0
  4. package/dist/cjs/llm/adapters/anthropic.js.map +1 -0
  5. package/dist/cjs/llm/adapters/base.js +100 -0
  6. package/dist/cjs/llm/adapters/base.js.map +1 -0
  7. package/dist/cjs/llm/adapters/index.js +22 -0
  8. package/dist/cjs/llm/adapters/index.js.map +1 -0
  9. package/dist/cjs/llm/adapters/ollama.js +149 -0
  10. package/dist/cjs/llm/adapters/ollama.js.map +1 -0
  11. package/dist/cjs/llm/adapters/openai.js +126 -0
  12. package/dist/cjs/llm/adapters/openai.js.map +1 -0
  13. package/dist/cjs/llm/index.js +34 -5
  14. package/dist/cjs/llm/index.js.map +1 -1
  15. package/dist/cjs/llm/orchestrator.js +219 -0
  16. package/dist/cjs/llm/orchestrator.js.map +1 -0
  17. package/dist/cjs/llm/prompts.js +367 -0
  18. package/dist/cjs/llm/prompts.js.map +1 -0
  19. package/dist/cjs/parsers/base.js +189 -0
  20. package/dist/cjs/parsers/base.js.map +1 -0
  21. package/dist/cjs/parsers/demo.js +159 -0
  22. package/dist/cjs/parsers/demo.js.map +1 -0
  23. package/dist/cjs/parsers/extractor.js +191 -0
  24. package/dist/cjs/parsers/extractor.js.map +1 -0
  25. package/dist/cjs/parsers/index.js +43 -4
  26. package/dist/cjs/parsers/index.js.map +1 -1
  27. package/dist/cjs/parsers/json.js +157 -0
  28. package/dist/cjs/parsers/json.js.map +1 -0
  29. package/dist/cjs/parsers/markdown.js +168 -0
  30. package/dist/cjs/parsers/markdown.js.map +1 -0
  31. package/dist/cjs/parsers/samples.js +139 -0
  32. package/dist/cjs/parsers/samples.js.map +1 -0
  33. package/dist/cjs/storage/base.js +231 -0
  34. package/dist/cjs/storage/base.js.map +1 -0
  35. package/dist/cjs/storage/errors.js +128 -0
  36. package/dist/cjs/storage/errors.js.map +1 -0
  37. package/dist/cjs/storage/index.js +92 -5
  38. package/dist/cjs/storage/index.js.map +1 -1
  39. package/dist/cjs/storage/levelgraph.js +855 -0
  40. package/dist/cjs/storage/levelgraph.js.map +1 -0
  41. package/dist/cjs/storage/memory.js +447 -0
  42. package/dist/cjs/storage/memory.js.map +1 -0
  43. package/dist/cjs/storage/neo4j.js +866 -0
  44. package/dist/cjs/storage/neo4j.js.map +1 -0
  45. package/dist/cjs/storage/seeds.js +565 -0
  46. package/dist/cjs/storage/seeds.js.map +1 -0
  47. package/dist/cjs/types/llm.js +8 -0
  48. package/dist/cjs/types/llm.js.map +1 -0
  49. package/dist/cjs/types/parser.js +8 -0
  50. package/dist/cjs/types/parser.js.map +1 -0
  51. package/dist/esm/llm/adapters/anthropic.js +119 -0
  52. package/dist/esm/llm/adapters/anthropic.js.map +1 -0
  53. package/dist/esm/llm/adapters/base.js +95 -0
  54. package/dist/esm/llm/adapters/base.js.map +1 -0
  55. package/dist/esm/llm/adapters/index.js +10 -0
  56. package/dist/esm/llm/adapters/index.js.map +1 -0
  57. package/dist/esm/llm/adapters/ollama.js +144 -0
  58. package/dist/esm/llm/adapters/ollama.js.map +1 -0
  59. package/dist/esm/llm/adapters/openai.js +121 -0
  60. package/dist/esm/llm/adapters/openai.js.map +1 -0
  61. package/dist/esm/llm/index.js +12 -6
  62. package/dist/esm/llm/index.js.map +1 -1
  63. package/dist/esm/llm/orchestrator.js +214 -0
  64. package/dist/esm/llm/orchestrator.js.map +1 -0
  65. package/dist/esm/llm/prompts.js +360 -0
  66. package/dist/esm/llm/prompts.js.map +1 -0
  67. package/dist/esm/parsers/base.js +179 -0
  68. package/dist/esm/parsers/base.js.map +1 -0
  69. package/dist/esm/parsers/demo.js +154 -0
  70. package/dist/esm/parsers/demo.js.map +1 -0
  71. package/dist/esm/parsers/extractor.js +187 -0
  72. package/dist/esm/parsers/extractor.js.map +1 -0
  73. package/dist/esm/parsers/index.js +24 -5
  74. package/dist/esm/parsers/index.js.map +1 -1
  75. package/dist/esm/parsers/json.js +153 -0
  76. package/dist/esm/parsers/json.js.map +1 -0
  77. package/dist/esm/parsers/markdown.js +164 -0
  78. package/dist/esm/parsers/markdown.js.map +1 -0
  79. package/dist/esm/parsers/samples.js +136 -0
  80. package/dist/esm/parsers/samples.js.map +1 -0
  81. package/dist/esm/storage/base.js +221 -0
  82. package/dist/esm/storage/base.js.map +1 -0
  83. package/dist/esm/storage/errors.js +116 -0
  84. package/dist/esm/storage/errors.js.map +1 -0
  85. package/dist/esm/storage/index.js +71 -6
  86. package/dist/esm/storage/index.js.map +1 -1
  87. package/dist/esm/storage/levelgraph.js +818 -0
  88. package/dist/esm/storage/levelgraph.js.map +1 -0
  89. package/dist/esm/storage/memory.js +443 -0
  90. package/dist/esm/storage/memory.js.map +1 -0
  91. package/dist/esm/storage/neo4j.js +829 -0
  92. package/dist/esm/storage/neo4j.js.map +1 -0
  93. package/dist/esm/storage/seeds.js +561 -0
  94. package/dist/esm/storage/seeds.js.map +1 -0
  95. package/dist/esm/types/llm.js +7 -0
  96. package/dist/esm/types/llm.js.map +1 -0
  97. package/dist/esm/types/parser.js +7 -0
  98. package/dist/esm/types/parser.js.map +1 -0
  99. package/dist/types/llm/adapters/anthropic.d.ts +21 -0
  100. package/dist/types/llm/adapters/anthropic.d.ts.map +1 -0
  101. package/dist/types/llm/adapters/base.d.ts +46 -0
  102. package/dist/types/llm/adapters/base.d.ts.map +1 -0
  103. package/dist/types/llm/adapters/index.d.ts +11 -0
  104. package/dist/types/llm/adapters/index.d.ts.map +1 -0
  105. package/dist/types/llm/adapters/ollama.d.ts +30 -0
  106. package/dist/types/llm/adapters/ollama.d.ts.map +1 -0
  107. package/dist/types/llm/adapters/openai.d.ts +22 -0
  108. package/dist/types/llm/adapters/openai.d.ts.map +1 -0
  109. package/dist/types/llm/index.d.ts +5 -0
  110. package/dist/types/llm/index.d.ts.map +1 -1
  111. package/dist/types/llm/orchestrator.d.ts +35 -0
  112. package/dist/types/llm/orchestrator.d.ts.map +1 -0
  113. package/dist/types/llm/prompts.d.ts +269 -0
  114. package/dist/types/llm/prompts.d.ts.map +1 -0
  115. package/dist/types/parsers/base.d.ts +39 -0
  116. package/dist/types/parsers/base.d.ts.map +1 -0
  117. package/dist/types/parsers/demo.d.ts +87 -0
  118. package/dist/types/parsers/demo.d.ts.map +1 -0
  119. package/dist/types/parsers/extractor.d.ts +43 -0
  120. package/dist/types/parsers/extractor.d.ts.map +1 -0
  121. package/dist/types/parsers/index.d.ts +10 -0
  122. package/dist/types/parsers/index.d.ts.map +1 -1
  123. package/dist/types/parsers/json.d.ts +71 -0
  124. package/dist/types/parsers/json.d.ts.map +1 -0
  125. package/dist/types/parsers/markdown.d.ts +43 -0
  126. package/dist/types/parsers/markdown.d.ts.map +1 -0
  127. package/dist/types/parsers/samples.d.ts +27 -0
  128. package/dist/types/parsers/samples.d.ts.map +1 -0
  129. package/dist/types/storage/base.d.ts +39 -0
  130. package/dist/types/storage/base.d.ts.map +1 -0
  131. package/dist/types/storage/errors.d.ts +74 -0
  132. package/dist/types/storage/errors.d.ts.map +1 -0
  133. package/dist/types/storage/index.d.ts +50 -2
  134. package/dist/types/storage/index.d.ts.map +1 -1
  135. package/dist/types/storage/levelgraph.d.ts +92 -0
  136. package/dist/types/storage/levelgraph.d.ts.map +1 -0
  137. package/dist/types/storage/memory.d.ts +70 -0
  138. package/dist/types/storage/memory.d.ts.map +1 -0
  139. package/dist/types/storage/neo4j.d.ts +88 -0
  140. package/dist/types/storage/neo4j.d.ts.map +1 -0
  141. package/dist/types/storage/seeds.d.ts +27 -0
  142. package/dist/types/storage/seeds.d.ts.map +1 -0
  143. package/dist/types/types/index.d.ts +2 -0
  144. package/dist/types/types/index.d.ts.map +1 -1
  145. package/dist/types/types/llm.d.ts +298 -0
  146. package/dist/types/types/llm.d.ts.map +1 -0
  147. package/dist/types/types/parser.d.ts +208 -0
  148. package/dist/types/types/parser.d.ts.map +1 -0
  149. package/package.json +4 -2
  150. package/scripts/postinstall.js +68 -0
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Base class and utilities for storage adapters
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ import { createSkillId, createEdgeId } from '../types/index.js';
7
+ import { NotConnectedError, ValidationError } from './errors.js';
8
+ /**
9
+ * Generate a unique ID with optional prefix
10
+ */
11
+ export function generateId(prefix = '') {
12
+ const timestamp = Date.now().toString(36);
13
+ const random = Math.random().toString(36).substring(2, 10);
14
+ return prefix ? `${prefix}_${timestamp}${random}` : `${timestamp}${random}`;
15
+ }
16
+ /**
17
+ * Get current ISO timestamp
18
+ */
19
+ export function nowISO() {
20
+ return new Date().toISOString();
21
+ }
22
+ /**
23
+ * Convert SkillNodeInput to full SkillNode with generated fields
24
+ */
25
+ export function inputToSkillNode(input) {
26
+ const now = nowISO();
27
+ const node = {
28
+ id: input.id ?? createSkillId(generateId('skill')),
29
+ name: input.name,
30
+ description: input.description,
31
+ bloomLevel: input.bloomLevel,
32
+ difficulty: input.difficulty,
33
+ isThresholdConcept: input.isThresholdConcept,
34
+ masteryThreshold: input.masteryThreshold,
35
+ estimatedMinutes: input.estimatedMinutes,
36
+ tags: input.tags,
37
+ metadata: input.metadata,
38
+ createdAt: now,
39
+ updatedAt: now,
40
+ };
41
+ // Only add optional fields if they have values
42
+ if (input.standardAlignment !== undefined) {
43
+ node.standardAlignment = input.standardAlignment;
44
+ }
45
+ if (input.domain !== undefined) {
46
+ node.domain = input.domain;
47
+ }
48
+ if (input.gradeLevel !== undefined) {
49
+ node.gradeLevel = input.gradeLevel;
50
+ }
51
+ return node;
52
+ }
53
+ /**
54
+ * Convert PrerequisiteEdgeInput to full PrerequisiteEdge with generated fields
55
+ */
56
+ export function inputToEdge(input) {
57
+ const edge = {
58
+ id: input.id ?? createEdgeId(generateId('edge')),
59
+ sourceId: input.sourceId,
60
+ targetId: input.targetId,
61
+ strength: input.strength,
62
+ type: input.type,
63
+ metadata: input.metadata,
64
+ createdAt: nowISO(),
65
+ };
66
+ // Only add optional fields if they have values
67
+ if (input.reasoning !== undefined) {
68
+ edge.reasoning = input.reasoning;
69
+ }
70
+ return edge;
71
+ }
72
+ /**
73
+ * Validate skill input data
74
+ */
75
+ export function validateSkillInput(input) {
76
+ if (!input.name || input.name.trim().length === 0) {
77
+ throw new ValidationError('Skill name is required', 'name');
78
+ }
79
+ if (input.difficulty < 0 || input.difficulty > 1) {
80
+ throw new ValidationError('Difficulty must be between 0 and 1', 'difficulty', input.difficulty);
81
+ }
82
+ if (input.masteryThreshold < 0 || input.masteryThreshold > 1) {
83
+ throw new ValidationError('Mastery threshold must be between 0 and 1', 'masteryThreshold', input.masteryThreshold);
84
+ }
85
+ if (input.estimatedMinutes < 0) {
86
+ throw new ValidationError('Estimated minutes cannot be negative', 'estimatedMinutes', input.estimatedMinutes);
87
+ }
88
+ }
89
+ /**
90
+ * Validate edge input data
91
+ */
92
+ export function validateEdgeInput(input) {
93
+ if (!input.sourceId) {
94
+ throw new ValidationError('Source skill ID is required', 'sourceId');
95
+ }
96
+ if (!input.targetId) {
97
+ throw new ValidationError('Target skill ID is required', 'targetId');
98
+ }
99
+ if (input.sourceId === input.targetId) {
100
+ throw new ValidationError('Edge cannot reference the same skill as source and target', 'sourceId', input.sourceId);
101
+ }
102
+ if (input.strength < 0 || input.strength > 1) {
103
+ throw new ValidationError('Edge strength must be between 0 and 1', 'strength', input.strength);
104
+ }
105
+ }
106
+ /**
107
+ * Ensure adapter is connected before operations
108
+ */
109
+ export function requireConnection(connected) {
110
+ if (!connected) {
111
+ throw new NotConnectedError();
112
+ }
113
+ }
114
+ /**
115
+ * Calculate graph statistics from nodes and edges
116
+ */
117
+ export function calculateStats(nodes, edges) {
118
+ const inDegree = new Map();
119
+ const outDegree = new Map();
120
+ // Initialize degree maps
121
+ for (const node of nodes) {
122
+ inDegree.set(node.id, 0);
123
+ outDegree.set(node.id, 0);
124
+ }
125
+ // Count degrees
126
+ for (const edge of edges) {
127
+ const source = edge.sourceId;
128
+ const target = edge.targetId;
129
+ outDegree.set(source, (outDegree.get(source) || 0) + 1);
130
+ inDegree.set(target, (inDegree.get(target) || 0) + 1);
131
+ }
132
+ // Count roots (no prerequisites / in-degree 0)
133
+ let rootCount = 0;
134
+ let leafCount = 0;
135
+ for (const node of nodes) {
136
+ if (inDegree.get(node.id) === 0)
137
+ rootCount++;
138
+ if (outDegree.get(node.id) === 0)
139
+ leafCount++;
140
+ }
141
+ // Calculate bloom distribution
142
+ const bloomDistribution = {
143
+ remember: 0,
144
+ understand: 0,
145
+ apply: 0,
146
+ analyze: 0,
147
+ evaluate: 0,
148
+ create: 0,
149
+ };
150
+ for (const node of nodes) {
151
+ bloomDistribution[node.bloomLevel] =
152
+ (bloomDistribution[node.bloomLevel] || 0) + 1;
153
+ }
154
+ // Calculate difficulty distribution
155
+ const difficultyDistribution = {
156
+ foundational: 0,
157
+ basic: 0,
158
+ intermediate: 0,
159
+ advanced: 0,
160
+ expert: 0,
161
+ };
162
+ for (const node of nodes) {
163
+ if (node.difficulty <= 0.2)
164
+ difficultyDistribution.foundational++;
165
+ else if (node.difficulty <= 0.4)
166
+ difficultyDistribution.basic++;
167
+ else if (node.difficulty <= 0.6)
168
+ difficultyDistribution.intermediate++;
169
+ else if (node.difficulty <= 0.8)
170
+ difficultyDistribution.advanced++;
171
+ else
172
+ difficultyDistribution.expert++;
173
+ }
174
+ // Calculate max depth via BFS from all roots
175
+ let maxDepth = 0;
176
+ const adjacency = new Map();
177
+ for (const edge of edges) {
178
+ const source = edge.sourceId;
179
+ const target = edge.targetId;
180
+ if (!adjacency.has(source))
181
+ adjacency.set(source, []);
182
+ adjacency.get(source).push(target);
183
+ }
184
+ function bfsMaxDepth(startId) {
185
+ const queue = [
186
+ { id: startId, depth: 0 },
187
+ ];
188
+ let max = 0;
189
+ while (queue.length > 0) {
190
+ const { id, depth } = queue.shift();
191
+ max = Math.max(max, depth);
192
+ const neighbors = adjacency.get(id) || [];
193
+ for (const neighbor of neighbors) {
194
+ queue.push({ id: neighbor, depth: depth + 1 });
195
+ }
196
+ }
197
+ return max;
198
+ }
199
+ // Find max depth from all root nodes
200
+ for (const node of nodes) {
201
+ if (inDegree.get(node.id) === 0) {
202
+ maxDepth = Math.max(maxDepth, bfsMaxDepth(node.id));
203
+ }
204
+ }
205
+ // Calculate averages
206
+ const totalInDegree = Array.from(inDegree.values()).reduce((a, b) => a + b, 0);
207
+ const totalOutDegree = Array.from(outDegree.values()).reduce((a, b) => a + b, 0);
208
+ return {
209
+ nodeCount: nodes.length,
210
+ edgeCount: edges.length,
211
+ thresholdConceptCount: nodes.filter((n) => n.isThresholdConcept).length,
212
+ rootNodeCount: rootCount,
213
+ leafNodeCount: leafCount,
214
+ maxDepth,
215
+ avgPrerequisites: nodes.length > 0 ? totalInDegree / nodes.length : 0,
216
+ avgDependents: nodes.length > 0 ? totalOutDegree / nodes.length : 0,
217
+ bloomDistribution,
218
+ difficultyDistribution,
219
+ };
220
+ }
221
+ //# 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,116 @@
1
+ /**
2
+ * Storage-specific errors for LearnGraph
3
+ *
4
+ * @packageDocumentation
5
+ */
6
+ /**
7
+ * Base error class for storage operations
8
+ */
9
+ export class StorageError extends Error {
10
+ code;
11
+ cause;
12
+ constructor(message, code, cause) {
13
+ super(message);
14
+ this.code = code;
15
+ this.cause = cause;
16
+ this.name = 'StorageError';
17
+ Error.captureStackTrace?.(this, this.constructor);
18
+ }
19
+ }
20
+ /**
21
+ * Thrown when connection to storage backend fails
22
+ */
23
+ export class ConnectionError extends StorageError {
24
+ constructor(message, cause) {
25
+ super(message, 'CONNECTION_ERROR', cause);
26
+ this.name = 'ConnectionError';
27
+ }
28
+ }
29
+ /**
30
+ * Thrown when attempting operation without active connection
31
+ */
32
+ export class NotConnectedError extends StorageError {
33
+ constructor() {
34
+ super('Not connected to storage backend', 'NOT_CONNECTED');
35
+ this.name = 'NotConnectedError';
36
+ }
37
+ }
38
+ /**
39
+ * Thrown when a skill or edge is not found
40
+ */
41
+ export class NotFoundError extends StorageError {
42
+ entityType;
43
+ entityId;
44
+ constructor(entityType, entityId) {
45
+ super(`${entityType} not found: ${entityId}`, 'NOT_FOUND');
46
+ this.entityType = entityType;
47
+ this.entityId = entityId;
48
+ this.name = 'NotFoundError';
49
+ }
50
+ }
51
+ /**
52
+ * Thrown when attempting to create a duplicate entity
53
+ */
54
+ export class DuplicateError extends StorageError {
55
+ entityType;
56
+ entityId;
57
+ constructor(entityType, entityId) {
58
+ super(`${entityType} already exists: ${entityId}`, 'DUPLICATE');
59
+ this.entityType = entityType;
60
+ this.entityId = entityId;
61
+ this.name = 'DuplicateError';
62
+ }
63
+ }
64
+ /**
65
+ * Thrown when edge references non-existent skill
66
+ */
67
+ export class ReferenceError extends StorageError {
68
+ edgeId;
69
+ missingSkillId;
70
+ role;
71
+ constructor(edgeId, missingSkillId, role) {
72
+ super(`Edge ${edgeId} references non-existent ${role} skill: ${missingSkillId}`, 'REFERENCE_ERROR');
73
+ this.edgeId = edgeId;
74
+ this.missingSkillId = missingSkillId;
75
+ this.role = role;
76
+ this.name = 'ReferenceError';
77
+ }
78
+ }
79
+ /**
80
+ * Thrown when data validation fails
81
+ */
82
+ export class ValidationError extends StorageError {
83
+ field;
84
+ value;
85
+ constructor(message, field, value) {
86
+ super(message, 'VALIDATION_ERROR');
87
+ this.field = field;
88
+ this.value = value;
89
+ this.name = 'ValidationError';
90
+ }
91
+ }
92
+ /**
93
+ * Thrown when a query times out
94
+ */
95
+ export class TimeoutError extends StorageError {
96
+ operation;
97
+ timeoutMs;
98
+ constructor(operation, timeoutMs) {
99
+ super(`Operation "${operation}" timed out after ${timeoutMs}ms`, 'TIMEOUT');
100
+ this.operation = operation;
101
+ this.timeoutMs = timeoutMs;
102
+ this.name = 'TimeoutError';
103
+ }
104
+ }
105
+ /**
106
+ * Thrown when a cycle is detected in the graph
107
+ */
108
+ export class CycleDetectedError extends StorageError {
109
+ path;
110
+ constructor(path) {
111
+ super(`Cycle detected in graph: ${path.join(' -> ')}`, 'CYCLE_DETECTED');
112
+ this.path = path;
113
+ this.name = 'CycleDetectedError';
114
+ }
115
+ }
116
+ //# 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,11 +1,76 @@
1
1
  /**
2
- * Graph storage adapters
2
+ * Graph storage adapters for LearnGraph
3
+ *
4
+ * Provides a unified interface for storing skill graphs with multiple
5
+ * backend options:
6
+ * - **MemoryStorage**: In-memory storage for testing
7
+ * - **LevelGraphStorage**: Browser/local storage using triples
8
+ * - **Neo4jStorage**: Production graph database
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { MemoryStorage, Neo4jStorage, LevelGraphStorage } from 'learngraph/storage';
13
+ *
14
+ * // For testing
15
+ * const testStorage = new MemoryStorage();
16
+ * await testStorage.connect({ backend: 'memory' });
17
+ *
18
+ * // For browser/local development
19
+ * const localStorage = new LevelGraphStorage();
20
+ * await localStorage.connect({ backend: 'levelgraph', path: './my-graph' });
21
+ *
22
+ * // For production
23
+ * const prodStorage = new Neo4jStorage();
24
+ * await prodStorage.connect({
25
+ * backend: 'neo4j',
26
+ * uri: 'bolt://localhost:7687',
27
+ * username: 'neo4j',
28
+ * password: 'password',
29
+ * });
30
+ *
31
+ * // Same API for all!
32
+ * const skill = await storage.createSkill({ ... });
33
+ * const prereqs = await storage.getPrerequisitesOf(skill.id);
34
+ * ```
3
35
  *
4
36
  * @packageDocumentation
5
37
  */
6
- export {};
7
- // Storage adapters will be implemented in Phase 2
8
- // export { Neo4jStorage } from './neo4j.js';
9
- // export { LevelGraphStorage } from './levelgraph.js';
10
- // export { MemoryStorage } from './memory.js';
38
+ // ─────────────────────────────────────────────────────────────────────────────
39
+ // Storage Errors
40
+ // ─────────────────────────────────────────────────────────────────────────────
41
+ export { StorageError, ConnectionError, NotConnectedError, NotFoundError, DuplicateError, ReferenceError, ValidationError, TimeoutError, CycleDetectedError, } from './errors.js';
42
+ // ─────────────────────────────────────────────────────────────────────────────
43
+ // Base Utilities
44
+ // ─────────────────────────────────────────────────────────────────────────────
45
+ export { generateId, nowISO, inputToSkillNode, inputToEdge, validateSkillInput, validateEdgeInput, calculateStats, } from './base.js';
46
+ // ─────────────────────────────────────────────────────────────────────────────
47
+ // Storage Adapters
48
+ // ─────────────────────────────────────────────────────────────────────────────
49
+ export { MemoryStorage } from './memory.js';
50
+ export { LevelGraphStorage } from './levelgraph.js';
51
+ export { Neo4jStorage } from './neo4j.js';
52
+ import { MemoryStorage } from './memory.js';
53
+ import { LevelGraphStorage } from './levelgraph.js';
54
+ import { Neo4jStorage } from './neo4j.js';
55
+ /**
56
+ * Create a storage adapter based on configuration.
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const storage = createStorage({ backend: 'memory' });
61
+ * await storage.connect({ backend: 'memory' });
62
+ * ```
63
+ */
64
+ export function createStorage(config) {
65
+ switch (config.backend) {
66
+ case 'memory':
67
+ return new MemoryStorage();
68
+ case 'levelgraph':
69
+ return new LevelGraphStorage();
70
+ case 'neo4j':
71
+ return new Neo4jStorage();
72
+ default:
73
+ throw new Error(`Unknown storage backend: ${config.backend}`);
74
+ }
75
+ }
11
76
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAeH,kDAAkD;AAClD,6CAA6C;AAC7C,uDAAuD;AACvD,+CAA+C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAkBH,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAChF,OAAO,EACL,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,cAAc,EACd,eAAe,EACf,YAAY,EACZ,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,gFAAgF;AAChF,iBAAiB;AACjB,gFAAgF;AAChF,OAAO,EACL,UAAU,EACV,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,MAAqB;IACjD,QAAQ,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,QAAQ;YACX,OAAO,IAAI,aAAa,EAAE,CAAC;QAC7B,KAAK,YAAY;YACf,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACjC,KAAK,OAAO;YACV,OAAO,IAAI,YAAY,EAAE,CAAC;QAC5B;YACE,MAAM,IAAI,KAAK,CAAC,4BAA6B,MAAwB,CAAC,OAAO,EAAE,CAAC,CAAC;IACrF,CAAC;AACH,CAAC"}