@linklabjs/core 0.1.0 → 0.1.2

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 (206) hide show
  1. package/dist/api/DomainNode.d.ts +154 -0
  2. package/dist/api/DomainNode.d.ts.map +1 -0
  3. package/dist/api/DomainNode.js +1157 -0
  4. package/dist/api/DomainNode.js.map +1 -0
  5. package/dist/api/Graph.d.ts +117 -0
  6. package/dist/api/Graph.d.ts.map +1 -0
  7. package/dist/api/Graph.js +212 -0
  8. package/dist/api/Graph.js.map +1 -0
  9. package/dist/api/PathBuilder.d.ts +76 -0
  10. package/dist/api/PathBuilder.d.ts.map +1 -0
  11. package/dist/api/PathBuilder.js +182 -0
  12. package/dist/api/PathBuilder.js.map +1 -0
  13. package/dist/api/index.d.ts +8 -0
  14. package/dist/api/index.d.ts.map +1 -0
  15. package/dist/api/index.js +7 -0
  16. package/dist/api/index.js.map +1 -0
  17. package/dist/api/loadGraph.d.ts +57 -0
  18. package/dist/api/loadGraph.d.ts.map +1 -0
  19. package/dist/api/loadGraph.js +153 -0
  20. package/dist/api/loadGraph.js.map +1 -0
  21. package/dist/api/test-api.d.ts +9 -0
  22. package/dist/api/test-api.d.ts.map +1 -0
  23. package/dist/api/test-api.js +133 -0
  24. package/dist/api/test-api.js.map +1 -0
  25. package/dist/api/test-domain.d.ts +13 -0
  26. package/dist/api/test-domain.d.ts.map +1 -0
  27. package/dist/api/test-domain.js +105 -0
  28. package/dist/api/test-domain.js.map +1 -0
  29. package/dist/api/types.d.ts +69 -0
  30. package/dist/api/types.d.ts.map +1 -0
  31. package/dist/api/types.js +22 -0
  32. package/dist/api/types.js.map +1 -0
  33. package/dist/config/synonyms.json +25 -0
  34. package/dist/core/EventBus.d.ts +56 -0
  35. package/dist/core/EventBus.d.ts.map +1 -0
  36. package/dist/core/EventBus.js +147 -0
  37. package/dist/core/EventBus.js.map +1 -0
  38. package/dist/core/GraphEvents.d.ts +118 -0
  39. package/dist/core/GraphEvents.d.ts.map +1 -0
  40. package/dist/core/GraphEvents.js +23 -0
  41. package/dist/core/GraphEvents.js.map +1 -0
  42. package/dist/core/PathFinder.d.ts +43 -0
  43. package/dist/core/PathFinder.d.ts.map +1 -0
  44. package/dist/core/PathFinder.js +264 -0
  45. package/dist/core/PathFinder.js.map +1 -0
  46. package/dist/formatters/BaseFormatter.d.ts +15 -0
  47. package/dist/formatters/BaseFormatter.d.ts.map +1 -0
  48. package/dist/formatters/BaseFormatter.js +9 -0
  49. package/dist/formatters/BaseFormatter.js.map +1 -0
  50. package/dist/graph/GraphAssembler.d.ts +14 -0
  51. package/dist/graph/GraphAssembler.d.ts.map +1 -0
  52. package/dist/graph/GraphAssembler.js +44 -0
  53. package/dist/graph/GraphAssembler.js.map +1 -0
  54. package/dist/graph/GraphCompiler.d.ts +37 -0
  55. package/dist/graph/GraphCompiler.d.ts.map +1 -0
  56. package/dist/graph/GraphCompiler.js +355 -0
  57. package/dist/graph/GraphCompiler.js.map +1 -0
  58. package/dist/graph/GraphExtractor.d.ts +21 -0
  59. package/dist/graph/GraphExtractor.d.ts.map +1 -0
  60. package/dist/graph/GraphExtractor.js +145 -0
  61. package/dist/graph/GraphExtractor.js.map +1 -0
  62. package/dist/graph/GraphOptimizer.d.ts +104 -0
  63. package/dist/graph/GraphOptimizer.d.ts.map +1 -0
  64. package/dist/graph/GraphOptimizer.js +306 -0
  65. package/dist/graph/GraphOptimizer.js.map +1 -0
  66. package/dist/graph/GraphTrainer.d.ts +52 -0
  67. package/dist/graph/GraphTrainer.d.ts.map +1 -0
  68. package/dist/graph/GraphTrainer.js +188 -0
  69. package/dist/graph/GraphTrainer.js.map +1 -0
  70. package/dist/http/LinkBuilder.d.ts +82 -0
  71. package/dist/http/LinkBuilder.d.ts.map +1 -0
  72. package/dist/http/LinkBuilder.js +190 -0
  73. package/dist/http/LinkBuilder.js.map +1 -0
  74. package/dist/http/TrailRequest.d.ts +39 -0
  75. package/dist/http/TrailRequest.d.ts.map +1 -0
  76. package/dist/http/TrailRequest.js +22 -0
  77. package/dist/http/TrailRequest.js.map +1 -0
  78. package/dist/http/example-netflix.d.ts +6 -0
  79. package/dist/http/example-netflix.d.ts.map +1 -0
  80. package/dist/http/example-netflix.js +52 -0
  81. package/dist/http/example-netflix.js.map +1 -0
  82. package/dist/http/index.d.ts +32 -0
  83. package/dist/http/index.d.ts.map +1 -0
  84. package/dist/http/index.js +27 -0
  85. package/dist/http/index.js.map +1 -0
  86. package/dist/http/plugin.d.ts +110 -0
  87. package/dist/http/plugin.d.ts.map +1 -0
  88. package/dist/http/plugin.js +217 -0
  89. package/dist/http/plugin.js.map +1 -0
  90. package/dist/index.d.ts +55 -0
  91. package/dist/index.d.ts.map +1 -0
  92. package/dist/index.js +71 -0
  93. package/dist/index.js.map +1 -0
  94. package/dist/instrumentation/TelemetryShim.d.ts +114 -0
  95. package/dist/instrumentation/TelemetryShim.d.ts.map +1 -0
  96. package/dist/instrumentation/TelemetryShim.js +107 -0
  97. package/dist/instrumentation/TelemetryShim.js.map +1 -0
  98. package/dist/navigation/NavigationEngine.d.ts +69 -0
  99. package/dist/navigation/NavigationEngine.d.ts.map +1 -0
  100. package/dist/navigation/NavigationEngine.js +361 -0
  101. package/dist/navigation/NavigationEngine.js.map +1 -0
  102. package/dist/navigation/Resolver.d.ts +35 -0
  103. package/dist/navigation/Resolver.d.ts.map +1 -0
  104. package/dist/navigation/Resolver.js +113 -0
  105. package/dist/navigation/Resolver.js.map +1 -0
  106. package/dist/navigation/Scheduler.d.ts +36 -0
  107. package/dist/navigation/Scheduler.d.ts.map +1 -0
  108. package/dist/navigation/Scheduler.js +107 -0
  109. package/dist/navigation/Scheduler.js.map +1 -0
  110. package/dist/navigation/Trail.d.ts +129 -0
  111. package/dist/navigation/Trail.d.ts.map +1 -0
  112. package/dist/navigation/Trail.js +202 -0
  113. package/dist/navigation/Trail.js.map +1 -0
  114. package/dist/navigation/TrailParser.d.ts +96 -0
  115. package/dist/navigation/TrailParser.d.ts.map +1 -0
  116. package/dist/navigation/TrailParser.js +180 -0
  117. package/dist/navigation/TrailParser.js.map +1 -0
  118. package/dist/navigation/index.d.ts +10 -0
  119. package/dist/navigation/index.d.ts.map +1 -0
  120. package/dist/navigation/index.js +9 -0
  121. package/dist/navigation/index.js.map +1 -0
  122. package/dist/providers/MockProvider.d.ts +29 -0
  123. package/dist/providers/MockProvider.d.ts.map +1 -0
  124. package/dist/providers/MockProvider.js +55 -0
  125. package/dist/providers/MockProvider.js.map +1 -0
  126. package/dist/providers/PostgresProvider.d.ts +46 -0
  127. package/dist/providers/PostgresProvider.d.ts.map +1 -0
  128. package/dist/providers/PostgresProvider.js +152 -0
  129. package/dist/providers/PostgresProvider.js.map +1 -0
  130. package/dist/runtime/CompiledGraphEngine.d.ts +74 -0
  131. package/dist/runtime/CompiledGraphEngine.d.ts.map +1 -0
  132. package/dist/runtime/CompiledGraphEngine.js +211 -0
  133. package/dist/runtime/CompiledGraphEngine.js.map +1 -0
  134. package/dist/runtime/DataLoader.d.ts +90 -0
  135. package/dist/runtime/DataLoader.d.ts.map +1 -0
  136. package/dist/runtime/DataLoader.js +178 -0
  137. package/dist/runtime/DataLoader.js.map +1 -0
  138. package/dist/runtime/Engine.d.ts +36 -0
  139. package/dist/runtime/Engine.d.ts.map +1 -0
  140. package/dist/runtime/Engine.js +128 -0
  141. package/dist/runtime/Engine.js.map +1 -0
  142. package/dist/runtime/QueryEngine.d.ts +80 -0
  143. package/dist/runtime/QueryEngine.d.ts.map +1 -0
  144. package/dist/runtime/QueryEngine.js +188 -0
  145. package/dist/runtime/QueryEngine.js.map +1 -0
  146. package/dist/scenarios/test-metro-paris/config.json +6 -0
  147. package/dist/scenarios/test-metro-paris/graph.json +16325 -0
  148. package/dist/scenarios/test-metro-paris/queries.d.ts +22 -0
  149. package/dist/scenarios/test-metro-paris/queries.d.ts.map +1 -0
  150. package/dist/scenarios/test-metro-paris/queries.js +128 -0
  151. package/dist/scenarios/test-metro-paris/queries.js.map +1 -0
  152. package/dist/scenarios/test-metro-paris/stack.json +1 -0
  153. package/dist/scenarios/test-musicians/config.json +10 -0
  154. package/dist/scenarios/test-musicians/graph.json +20 -0
  155. package/dist/scenarios/test-musicians/stack.json +1 -0
  156. package/dist/scenarios/test-netflix/actions.d.ts +14 -0
  157. package/dist/scenarios/test-netflix/actions.d.ts.map +1 -0
  158. package/dist/scenarios/test-netflix/actions.js +86 -0
  159. package/dist/scenarios/test-netflix/actions.js.map +1 -0
  160. package/dist/scenarios/test-netflix/config.json +6 -0
  161. package/dist/scenarios/test-netflix/data/categories.json +1 -0
  162. package/dist/scenarios/test-netflix/data/companies.json +1 -0
  163. package/dist/scenarios/test-netflix/data/credits.json +19797 -0
  164. package/dist/scenarios/test-netflix/data/departments.json +18 -0
  165. package/dist/scenarios/test-netflix/data/jobs.json +142 -0
  166. package/dist/scenarios/test-netflix/data/movies.json +3497 -0
  167. package/dist/scenarios/test-netflix/data/people.json +1 -0
  168. package/dist/scenarios/test-netflix/data/synonyms.json +7 -0
  169. package/dist/scenarios/test-netflix/data/users.json +70 -0
  170. package/dist/scenarios/test-netflix/graph.json +1017 -0
  171. package/dist/scenarios/test-netflix/queries.d.ts +29 -0
  172. package/dist/scenarios/test-netflix/queries.d.ts.map +1 -0
  173. package/dist/scenarios/test-netflix/queries.js +134 -0
  174. package/dist/scenarios/test-netflix/queries.js.map +1 -0
  175. package/dist/scenarios/test-netflix/stack.json +14 -0
  176. package/dist/schema/GraphBuilder.d.ts +9 -0
  177. package/dist/schema/GraphBuilder.d.ts.map +1 -0
  178. package/dist/schema/GraphBuilder.js +90 -0
  179. package/dist/schema/GraphBuilder.js.map +1 -0
  180. package/dist/schema/JsonSchemaExtractor.d.ts +21 -0
  181. package/dist/schema/JsonSchemaExtractor.d.ts.map +1 -0
  182. package/dist/schema/JsonSchemaExtractor.js +88 -0
  183. package/dist/schema/JsonSchemaExtractor.js.map +1 -0
  184. package/dist/schema/SchemaAnalyzer.d.ts +41 -0
  185. package/dist/schema/SchemaAnalyzer.d.ts.map +1 -0
  186. package/dist/schema/SchemaAnalyzer.js +144 -0
  187. package/dist/schema/SchemaAnalyzer.js.map +1 -0
  188. package/dist/schema/SchemaExtractor.d.ts +10 -0
  189. package/dist/schema/SchemaExtractor.d.ts.map +1 -0
  190. package/dist/schema/SchemaExtractor.js +90 -0
  191. package/dist/schema/SchemaExtractor.js.map +1 -0
  192. package/dist/schema/SynonymResolver.d.ts +55 -0
  193. package/dist/schema/SynonymResolver.d.ts.map +1 -0
  194. package/dist/schema/SynonymResolver.js +121 -0
  195. package/dist/schema/SynonymResolver.js.map +1 -0
  196. package/dist/scripts/dictionary.json +796 -0
  197. package/dist/scripts/graph.json +664 -0
  198. package/dist/scripts/regenerate.d.ts +23 -0
  199. package/dist/scripts/regenerate.d.ts.map +1 -0
  200. package/dist/scripts/regenerate.js +206 -0
  201. package/dist/scripts/regenerate.js.map +1 -0
  202. package/dist/types/index.d.ts +394 -0
  203. package/dist/types/index.d.ts.map +1 -0
  204. package/dist/types/index.js +21 -0
  205. package/dist/types/index.js.map +1 -0
  206. package/package.json +1 -1
@@ -0,0 +1,306 @@
1
+ /**
2
+ * GraphOptimizer — Analyse et rapport sur la qualité du graphe
3
+ *
4
+ * PRINCIPE : signaler, jamais détruire silencieusement.
5
+ *
6
+ * Chaque étape produit un rapport (warnings, suggestions).
7
+ * Le dev décide ensuite de ce qu'il fait.
8
+ *
9
+ * Seules deux opérations sont automatiques et non destructives :
10
+ * - Suppression des nœuds orphelins (aucune arête — objectivement inutiles)
11
+ * - Suppression des nœuds dead-end stricts (aucune arête entrante ET sortante)
12
+ *
13
+ * Les cycles sont DÉTECTÉS et CLASSIFIÉS, jamais supprimés :
14
+ * - SELF_LOOP : arête A → A (ex: Station-chatelet → Station-chatelet TRANSFER)
15
+ * - BIDIRECTIONAL : A → B et B → A (ex: CREATED + CREDITED — intentionnel)
16
+ * - STRUCTURAL_CYCLE : A → B → C → A (même type de relation — potentiellement problématique)
17
+ */
18
+ import { PathFinder } from '../core/PathFinder.js';
19
+ const DEFAULT_CONFIG = {
20
+ intentionalBidirectional: ['physical_reverse'],
21
+ intentionalSelfLoops: []
22
+ };
23
+ export class GraphOptimizer {
24
+ graph;
25
+ config;
26
+ constructor(graph, config = {}) {
27
+ this.graph = graph;
28
+ this.config = {
29
+ intentionalBidirectional: config.intentionalBidirectional ?? DEFAULT_CONFIG.intentionalBidirectional,
30
+ intentionalSelfLoops: config.intentionalSelfLoops ?? DEFAULT_CONFIG.intentionalSelfLoops
31
+ };
32
+ }
33
+ /**
34
+ * Pipeline complet — retourne un rapport, ne modifie pas le graphe original.
35
+ * Seuls orphelins et dead-ends stricts sont supprimés (safe).
36
+ */
37
+ optimize() {
38
+ console.log('🔧 GraphOptimizer — analyse du graphe...');
39
+ const before = {
40
+ nodes: this.graph.nodes.length,
41
+ edges: this.graph.edges.length
42
+ };
43
+ // Travailler sur une copie
44
+ const working = {
45
+ nodes: [...this.graph.nodes],
46
+ edges: [...this.graph.edges]
47
+ };
48
+ // Opérations safe (non destructives sémantiquement)
49
+ const removedOrphans = this.removeOrphans(working);
50
+ const removedDeadEnds = this.removeStrictDeadEnds(working);
51
+ // Analyse — rapport uniquement, pas de suppression
52
+ const cycles = this.detectCycles(working);
53
+ const duplicatePaths = this.detectDuplicatePaths(working);
54
+ const after = {
55
+ nodes: working.nodes.length,
56
+ edges: working.edges.length
57
+ };
58
+ // Résumé console
59
+ console.log(` Nœuds : ${before.nodes} → ${after.nodes} (-${before.nodes - after.nodes})`);
60
+ console.log(` Arêtes : ${before.edges} → ${after.edges} (-${before.edges - after.edges})`);
61
+ console.log(` Cycles : ${cycles.length} détecté(s)`);
62
+ console.log(` Chemins dupliqués : ${duplicatePaths.length} paire(s)`);
63
+ const isClean = cycles.filter(c => c.severity === 'WARNING').length === 0;
64
+ if (isClean) {
65
+ console.log(' ✅ Graphe propre');
66
+ }
67
+ else {
68
+ console.log(` ⚠️ ${cycles.filter(c => c.severity === 'WARNING').length} warning(s) à examiner`);
69
+ }
70
+ const report = {
71
+ graph: working,
72
+ summary: {
73
+ nodes: { before: before.nodes, after: after.nodes, removed: before.nodes - after.nodes },
74
+ edges: { before: before.edges, after: after.edges, removed: before.edges - after.edges }
75
+ },
76
+ cycles,
77
+ duplicatePaths,
78
+ removedOrphans,
79
+ removedDeadEnds,
80
+ isClean
81
+ };
82
+ this.printReport(report);
83
+ return report;
84
+ }
85
+ // ==================== CYCLES ====================
86
+ /**
87
+ * Détecte et classifie les cycles — ne supprime rien.
88
+ */
89
+ detectCycles(graph) {
90
+ const warnings = [];
91
+ const seen = new Set();
92
+ for (const edge of graph.edges) {
93
+ // 1. SELF_LOOP : A → A
94
+ if (edge.from === edge.to) {
95
+ const key = `SELF:${edge.name}`;
96
+ if (!seen.has(key)) {
97
+ seen.add(key);
98
+ const edgeType = edge.metadata?.type ?? edge.via ?? '';
99
+ const isIntentional = this.config.intentionalSelfLoops.includes(edgeType);
100
+ warnings.push({
101
+ type: 'SELF_LOOP',
102
+ severity: 'INFO',
103
+ edges: [edge.name ?? `${edge.from}→${edge.to}`],
104
+ nodes: [edge.from],
105
+ note: isIntentional
106
+ ? `Self-loop intentionnel (${edgeType}) sur ${edge.from}. Géré par Dijkstra.`
107
+ : `Boucle sur ${edge.from}. Géré par Dijkstra (visited), inoffensif.`
108
+ });
109
+ }
110
+ continue;
111
+ }
112
+ // 2. BIDIRECTIONAL : A → B et B → A
113
+ const reverse = graph.edges.find(e => e.from === edge.to && e.to === edge.from);
114
+ if (reverse) {
115
+ const key = [edge.from, edge.to].sort().join('↔');
116
+ if (!seen.has(key)) {
117
+ seen.add(key);
118
+ const typeA = edge.metadata?.type ?? '';
119
+ const typeB = reverse.metadata?.type ?? '';
120
+ const sameType = typeA === typeB;
121
+ const isIntentional = !sameType ||
122
+ this.config.intentionalBidirectional.includes(typeA) ||
123
+ this.config.intentionalBidirectional.includes(typeB);
124
+ warnings.push({
125
+ type: 'BIDIRECTIONAL',
126
+ severity: isIntentional ? 'INFO' : 'WARNING',
127
+ edges: [
128
+ edge.name ?? `${edge.from}→${edge.to}`,
129
+ reverse.name ?? `${reverse.from}→${reverse.to}`
130
+ ],
131
+ nodes: [edge.from, edge.to],
132
+ note: isIntentional
133
+ ? `Bidirectionnel intentionnel (${typeA} ↔ ${typeB}) — normal.`
134
+ : `Bidirectionnel de même type "${typeA}" non déclaré intentionnel — vérifier.`
135
+ });
136
+ }
137
+ }
138
+ }
139
+ // 3. STRUCTURAL_CYCLE : A → B → C → A (même type de relation)
140
+ const structuralCycles = this.detectStructuralCycles(graph);
141
+ warnings.push(...structuralCycles);
142
+ return warnings;
143
+ }
144
+ /**
145
+ * Détecte les cycles structurels A → B → ... → A
146
+ * en ne suivant que les arêtes du même type.
147
+ */
148
+ detectStructuralCycles(graph) {
149
+ const warnings = [];
150
+ const reportedCycles = new Set();
151
+ // Grouper les arêtes par type
152
+ const byType = new Map();
153
+ for (const edge of graph.edges) {
154
+ const type = edge.metadata?.type ?? edge.via ?? 'unknown';
155
+ if (!byType.has(type))
156
+ byType.set(type, []);
157
+ byType.get(type).push(edge);
158
+ }
159
+ for (const [type, edges] of byType) {
160
+ // DFS sur les arêtes de ce type uniquement
161
+ const visited = new Set();
162
+ const inPath = new Set();
163
+ const pathStack = [];
164
+ const dfs = (node) => {
165
+ if (inPath.has(node)) {
166
+ // Cycle trouvé — extraire le cycle
167
+ const cycleStart = pathStack.indexOf(node);
168
+ return pathStack.slice(cycleStart);
169
+ }
170
+ if (visited.has(node))
171
+ return null;
172
+ visited.add(node);
173
+ inPath.add(node);
174
+ pathStack.push(node);
175
+ const neighbors = edges.filter(e => e.from === node).map(e => e.to);
176
+ for (const neighbor of neighbors) {
177
+ const cycle = dfs(neighbor);
178
+ if (cycle)
179
+ return cycle;
180
+ }
181
+ pathStack.pop();
182
+ inPath.delete(node);
183
+ return null;
184
+ };
185
+ for (const edge of edges) {
186
+ const cycle = dfs(edge.from);
187
+ if (cycle) {
188
+ const key = [...cycle].sort().join(',');
189
+ if (!reportedCycles.has(key)) {
190
+ reportedCycles.add(key);
191
+ warnings.push({
192
+ type: 'STRUCTURAL_CYCLE',
193
+ severity: 'WARNING',
194
+ edges: [],
195
+ nodes: cycle,
196
+ note: `Cycle structurel sur le type "${type}" : ${cycle.join(' → ')} → ${cycle[0]}`
197
+ });
198
+ }
199
+ }
200
+ visited.clear();
201
+ inPath.clear();
202
+ pathStack.length = 0;
203
+ }
204
+ }
205
+ return warnings;
206
+ }
207
+ // ==================== SUPPRESSIONS SAFE ====================
208
+ /**
209
+ * Supprime les nœuds sans aucune arête (entrante ou sortante).
210
+ * Inoffensif — un nœud isolé ne contribue à aucune traversée.
211
+ */
212
+ removeOrphans(graph) {
213
+ const connected = new Set();
214
+ for (const edge of graph.edges) {
215
+ connected.add(edge.from);
216
+ connected.add(edge.to);
217
+ }
218
+ const orphans = graph.nodes
219
+ .filter(n => !connected.has(n.id))
220
+ .map(n => n.id);
221
+ graph.nodes = graph.nodes.filter(n => connected.has(n.id));
222
+ if (orphans.length > 0) {
223
+ console.log(` 🗑️ Orphelins supprimés : ${orphans.join(', ')}`);
224
+ }
225
+ return orphans;
226
+ }
227
+ /**
228
+ * Supprime les nœuds sans arête entrante ET sans arête sortante
229
+ * après suppression des orphelins.
230
+ * Différent de removeOrphans — cible les nœuds stricts.
231
+ */
232
+ removeStrictDeadEnds(graph) {
233
+ const hasIncoming = new Set();
234
+ const hasOutgoing = new Set();
235
+ for (const edge of graph.edges) {
236
+ hasOutgoing.add(edge.from);
237
+ hasIncoming.add(edge.to);
238
+ }
239
+ const deadEnds = graph.nodes
240
+ .filter(n => !hasIncoming.has(n.id) && !hasOutgoing.has(n.id))
241
+ .map(n => n.id);
242
+ // Déjà couverts par removeOrphans — cette passe est redondante
243
+ // mais explicite pour la lisibilité
244
+ graph.nodes = graph.nodes.filter(n => !deadEnds.includes(n.id));
245
+ return deadEnds;
246
+ }
247
+ // ==================== DUPLICATES ====================
248
+ /**
249
+ * Détecte les paires de nœuds avec plusieurs chemins possibles.
250
+ * Informatif — les chemins multiples sont souvent intentionnels (fallbacks).
251
+ */
252
+ detectDuplicatePaths(graph) {
253
+ const warnings = [];
254
+ const finder = new PathFinder(graph);
255
+ for (const from of graph.nodes) {
256
+ for (const to of graph.nodes) {
257
+ if (from.id === to.id)
258
+ continue;
259
+ try {
260
+ const paths = finder.findAllPaths(from.id, to.id, 5);
261
+ if (paths.length > 1) {
262
+ warnings.push({
263
+ from: from.id,
264
+ to: to.id,
265
+ paths: paths.map(p => p),
266
+ note: `${paths.length} chemins entre ${from.id} et ${to.id} — le plus court sera utilisé par défaut.`
267
+ });
268
+ }
269
+ }
270
+ catch {
271
+ // Ignorer les erreurs de traversée
272
+ }
273
+ }
274
+ }
275
+ return warnings;
276
+ }
277
+ // ==================== RAPPORT ====================
278
+ printReport(report) {
279
+ if (report.cycles.length === 0 && report.duplicatePaths.length === 0)
280
+ return;
281
+ console.log('\n📋 RAPPORT GraphOptimizer\n');
282
+ if (report.removedOrphans.length > 0) {
283
+ console.log(`🗑️ Orphelins supprimés (${report.removedOrphans.length}) :`);
284
+ report.removedOrphans.forEach(n => console.log(` - ${n}`));
285
+ }
286
+ // Cycles WARNING uniquement (les INFO sont attendus)
287
+ const cycleWarnings = report.cycles.filter(c => c.severity === 'WARNING');
288
+ if (cycleWarnings.length > 0) {
289
+ console.log(`\n⚠️ Cycles à examiner (${cycleWarnings.length}) :`);
290
+ cycleWarnings.forEach(c => {
291
+ console.log(` [${c.type}] ${c.note}`);
292
+ });
293
+ }
294
+ const cycleInfos = report.cycles.filter(c => c.severity === 'INFO');
295
+ if (cycleInfos.length > 0) {
296
+ console.log(`\nℹ️ Cycles intentionnels (${cycleInfos.length}) :`);
297
+ cycleInfos.forEach(c => {
298
+ console.log(` [${c.type}] ${c.note}`);
299
+ });
300
+ }
301
+ if (report.duplicatePaths.length > 0) {
302
+ console.log(`\nℹ️ Chemins multiples (${report.duplicatePaths.length} paires) — fallbacks disponibles`);
303
+ }
304
+ }
305
+ }
306
+ //# sourceMappingURL=GraphOptimizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphOptimizer.js","sourceRoot":"","sources":["../../src/graph/GraphOptimizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * GraphTrainer - Trains graph with real use cases
3
+ *
4
+ * Benchmarks all paths and assigns weights based on actual performance
5
+ */
6
+ import type { Graph, UseCase, MetricsMap, TrainingMetrics, Provider } from '../types/index.js';
7
+ export declare class GraphTrainer {
8
+ private graph;
9
+ private provider;
10
+ private metrics;
11
+ constructor(graph: Graph, provider: Provider);
12
+ /**
13
+ * Train graph with use cases
14
+ */
15
+ train(useCases: UseCase[]): Promise<MetricsMap>;
16
+ /**
17
+ * Train single use case
18
+ */
19
+ private trainUseCase;
20
+ /**
21
+ * Benchmark a specific path
22
+ */
23
+ private benchmarkPath;
24
+ /**
25
+ * Build SQL query for a path
26
+ */
27
+ private buildQuery;
28
+ /**
29
+ * Update graph weights based on metrics
30
+ */
31
+ updateWeights(): void;
32
+ /**
33
+ * Check if path uses edge
34
+ */
35
+ private pathUsesEdge;
36
+ /**
37
+ * Get training statistics
38
+ */
39
+ getStats(): {
40
+ total: number;
41
+ successful: number;
42
+ failed: number;
43
+ avgTime: number;
44
+ fastest: TrainingMetrics | undefined;
45
+ slowest: TrainingMetrics | undefined;
46
+ };
47
+ /**
48
+ * Get metrics map
49
+ */
50
+ getMetrics(): MetricsMap;
51
+ }
52
+ //# sourceMappingURL=GraphTrainer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphTrainer.d.ts","sourceRoot":"","sources":["../../src/graph/GraphTrainer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAG9F,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAO;IACpB,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,OAAO,CAAY;gBAEf,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ;IAM5C;;OAEG;IACG,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAcrD;;OAEG;YACW,YAAY;IAe1B;;OAEG;YACW,aAAa;IAgE3B;;OAEG;IACH,OAAO,CAAC,UAAU;IAiClB;;OAEG;IACH,aAAa,IAAI,IAAI;IA4BrB;;OAEG;IACH,OAAO,CAAC,YAAY;IASpB;;OAEG;IACH,QAAQ,IAAI;QACV,KAAK,EAAE,MAAM,CAAA;QACb,UAAU,EAAE,MAAM,CAAA;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,eAAe,GAAG,SAAS,CAAA;QACpC,OAAO,EAAE,eAAe,GAAG,SAAS,CAAA;KACrC;IA6BD;;OAEG;IACH,UAAU,IAAI,UAAU;CAGzB"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * GraphTrainer - Trains graph with real use cases
3
+ *
4
+ * Benchmarks all paths and assigns weights based on actual performance
5
+ */
6
+ import { PathFinder } from '../core/PathFinder.js';
7
+ export class GraphTrainer {
8
+ graph;
9
+ provider;
10
+ metrics;
11
+ constructor(graph, provider) {
12
+ this.graph = graph;
13
+ this.provider = provider;
14
+ this.metrics = new Map();
15
+ }
16
+ /**
17
+ * Train graph with use cases
18
+ */
19
+ async train(useCases) {
20
+ console.log(`🎓 Training graph with ${useCases.length} use cases...\n`);
21
+ for (const [index, useCase] of useCases.entries()) {
22
+ console.log(` [${index + 1}/${useCases.length}] ${useCase.description}`);
23
+ await this.trainUseCase(useCase);
24
+ }
25
+ console.log('\n✅ Training complete');
26
+ console.log(` Tested ${this.metrics.size} unique paths`);
27
+ return this.metrics;
28
+ }
29
+ /**
30
+ * Train single use case
31
+ */
32
+ async trainUseCase(useCase) {
33
+ const { from, to, sampleData } = useCase;
34
+ // Find all paths
35
+ const finder = new PathFinder(this.graph);
36
+ const paths = finder.findAllPaths(from, to);
37
+ console.log(` Found ${paths.length} possible paths`);
38
+ // Benchmark each path
39
+ for (const path of paths) {
40
+ await this.benchmarkPath(path, sampleData);
41
+ }
42
+ }
43
+ /**
44
+ * Benchmark a specific path
45
+ */
46
+ async benchmarkPath(path, sampleData) {
47
+ const pathKey = path.join('→');
48
+ try {
49
+ // Build SQL query
50
+ const query = this.buildQuery(path, sampleData);
51
+ // Execute multiple times for average
52
+ const iterations = 3;
53
+ const times = [];
54
+ for (let i = 0; i < iterations; i++) {
55
+ const start = performance.now();
56
+ await this.provider.query(query.sql, query.params);
57
+ const duration = performance.now() - start;
58
+ times.push(duration);
59
+ }
60
+ const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
61
+ const minTime = Math.min(...times);
62
+ const maxTime = Math.max(...times);
63
+ // Store metrics
64
+ if (!this.metrics.has(pathKey)) {
65
+ this.metrics.set(pathKey, {
66
+ path,
67
+ executions: 0,
68
+ successes: 0,
69
+ failures: 0,
70
+ totalTime: 0,
71
+ avgTime: 0,
72
+ minTime: Infinity,
73
+ maxTime: 0,
74
+ used: true
75
+ });
76
+ }
77
+ const metric = this.metrics.get(pathKey);
78
+ metric.executions += iterations;
79
+ metric.successes = (metric.successes || 0) + iterations;
80
+ metric.totalTime += avgTime * iterations;
81
+ metric.avgTime = metric.totalTime / metric.executions;
82
+ metric.minTime = Math.min(metric.minTime, minTime);
83
+ metric.maxTime = Math.max(metric.maxTime, maxTime);
84
+ console.log(` ✓ ${pathKey}: ${avgTime.toFixed(2)}ms avg`);
85
+ }
86
+ catch (err) {
87
+ console.log(` ✗ ${pathKey}: Failed - ${err.message}`);
88
+ // Mark as failed
89
+ this.metrics.set(pathKey, {
90
+ path,
91
+ executions: 0,
92
+ totalTime: 0,
93
+ avgTime: 0,
94
+ minTime: 0,
95
+ maxTime: 0,
96
+ used: false,
97
+ failed: true,
98
+ error: err.message
99
+ });
100
+ }
101
+ }
102
+ /**
103
+ * Build SQL query for a path
104
+ */
105
+ buildQuery(path, sampleData) {
106
+ // Start with first table
107
+ let sql = `SELECT * FROM ${path[0]}`;
108
+ const params = [];
109
+ // Add JOINs
110
+ for (let i = 1; i < path.length; i++) {
111
+ const from = path[i - 1];
112
+ const to = path[i];
113
+ // Find edge
114
+ const edge = this.graph.edges.find(e => e.from === from && e.to === to);
115
+ if (edge) {
116
+ sql += ` JOIN ${to} ON ${from}.${edge.via} = ${to}.id`;
117
+ }
118
+ }
119
+ // Add WHERE if sample data provided
120
+ if (sampleData?.id) {
121
+ sql += ` WHERE ${path[0]}.id = $${params.length + 1}`;
122
+ params.push(sampleData.id);
123
+ }
124
+ // Limit for safety
125
+ sql += ' LIMIT 100';
126
+ return { sql, params };
127
+ }
128
+ /**
129
+ * Update graph weights based on metrics
130
+ */
131
+ updateWeights() {
132
+ console.log('📊 Updating graph weights based on metrics...');
133
+ let updated = 0;
134
+ for (const edge of this.graph.edges) {
135
+ // Find all paths using this edge
136
+ const pathsWithEdge = Array.from(this.metrics.values()).filter(m => !m.failed && this.pathUsesEdge(m.path, edge));
137
+ if (pathsWithEdge.length === 0)
138
+ continue;
139
+ // Calculate new weight (average time)
140
+ const avgTime = pathsWithEdge.reduce((sum, m) => sum + m.avgTime, 0) / pathsWithEdge.length;
141
+ // Normalize to 0-100 scale
142
+ const newWeight = Math.min(100, avgTime);
143
+ if (edge.weight !== newWeight) {
144
+ edge.weight = newWeight;
145
+ updated++;
146
+ }
147
+ }
148
+ console.log(` Updated ${updated} edge weights`);
149
+ }
150
+ /**
151
+ * Check if path uses edge
152
+ */
153
+ pathUsesEdge(path, edge) {
154
+ for (let i = 0; i < path.length - 1; i++) {
155
+ if (path[i] === edge.from && path[i + 1] === edge.to) {
156
+ return true;
157
+ }
158
+ }
159
+ return false;
160
+ }
161
+ /**
162
+ * Get training statistics
163
+ */
164
+ getStats() {
165
+ const successful = Array.from(this.metrics.values()).filter(m => !m.failed);
166
+ const failed = Array.from(this.metrics.values()).filter(m => m.failed);
167
+ const avgTime = successful.length > 0
168
+ ? successful.reduce((sum, m) => sum + m.avgTime, 0) / successful.length
169
+ : 0;
170
+ const fastest = successful.reduce((min, m) => (!min || m.avgTime < min.avgTime ? m : min), undefined);
171
+ const slowest = successful.reduce((max, m) => (!max || m.avgTime > max.avgTime ? m : max), undefined);
172
+ return {
173
+ total: this.metrics.size,
174
+ successful: successful.length,
175
+ failed: failed.length,
176
+ avgTime,
177
+ fastest,
178
+ slowest
179
+ };
180
+ }
181
+ /**
182
+ * Get metrics map
183
+ */
184
+ getMetrics() {
185
+ return this.metrics;
186
+ }
187
+ }
188
+ //# sourceMappingURL=GraphTrainer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphTrainer.js","sourceRoot":"","sources":["../../src/graph/GraphTrainer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * LinkBuilder — Génère les liens HATEOAS depuis le graphe
3
+ *
4
+ * Logique pure, sans dépendance à Fastify.
5
+ * Prend un Trail + un Graph, retourne des liens navigables.
6
+ *
7
+ * Trois catégories de liens générés automatiquement :
8
+ *
9
+ * self — l'URL courante (Trail sérialisé)
10
+ * up — le parent (Trail sans la dernière frame)
11
+ * relations — toutes les arêtes sortantes du nœud courant
12
+ *
13
+ * Les liens émergent du graphe — le dev ne configure rien.
14
+ */
15
+ import type { Graph } from '../types/index.js';
16
+ import { Trail } from '../navigation/Trail.js';
17
+ export interface HateoasLink {
18
+ href: string;
19
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
20
+ templated?: boolean;
21
+ title?: string;
22
+ rel?: string;
23
+ }
24
+ export interface HateoasLinks {
25
+ self: HateoasLink;
26
+ up?: HateoasLink;
27
+ [relation: string]: HateoasLink | undefined;
28
+ }
29
+ export interface LinkBuilderOptions {
30
+ /** Préfixe ajouté à toutes les URLs générées — ex: '/api/v1' */
31
+ prefix?: string;
32
+ /** Inclure les arêtes inverses (retour vers le parent) */
33
+ includeReverse?: boolean;
34
+ /** Exclure certaines relations — ex: ['internal', 'debug'] */
35
+ exclude?: string[];
36
+ }
37
+ export declare class LinkBuilder {
38
+ private graph;
39
+ private options;
40
+ constructor(graph: Graph, options?: LinkBuilderOptions);
41
+ /**
42
+ * Génère les liens HATEOAS pour un Trail donné.
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const builder = new LinkBuilder(graph, { prefix: '/api' })
47
+ * const links = builder.from(trail)
48
+ * // {
49
+ * // self: { href: '/api/people/Nolan/movies' },
50
+ * // up: { href: '/api/people/Nolan' },
51
+ * // actors: { href: '/api/people/Nolan/movies/{id}/actors', templated: true },
52
+ * // ratings: { href: '/api/people/Nolan/movies/{id}/ratings', templated: true }
53
+ * // }
54
+ * ```
55
+ */
56
+ from(trail: Trail): HateoasLinks;
57
+ /**
58
+ * Génère les liens pour une collection de résultats.
59
+ * Chaque item reçoit ses propres liens self + relations.
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * // GET /people/Nolan/movies → liste de films
64
+ * const itemLinks = builder.forItems(trail, movies, 'id')
65
+ * // itemLinks[0] = { self: { href: '/people/Nolan/movies/1' }, actors: {...} }
66
+ * ```
67
+ */
68
+ forItems(trail: Trail, items: any[], idField?: string): HateoasLinks[];
69
+ /**
70
+ * Vérifie si une relation existe depuis un nœud donné.
71
+ * Utile pour les hooks d'access.check.
72
+ */
73
+ hasRelation(fromEntity: string, relation: string): boolean;
74
+ /**
75
+ * Retourne toutes les entités accessibles depuis un nœud.
76
+ */
77
+ reachableFrom(entity: string): string[];
78
+ private getOutgoingEdges;
79
+ private prefix;
80
+ private buildTitle;
81
+ }
82
+ //# sourceMappingURL=LinkBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkBuilder.d.ts","sourceRoot":"","sources":["../../src/http/LinkBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAa,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAE,KAAK,EAAE,MAAY,wBAAwB,CAAA;AAKpD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAM,MAAM,CAAA;IAChB,MAAM,EAAI,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAA;IACrD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,KAAK,CAAC,EAAI,MAAM,CAAA;IAChB,GAAG,CAAC,EAAM,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAG,WAAW,CAAA;IAClB,EAAE,CAAC,EAAI,WAAW,CAAA;IAClB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAA;CAC5C;AAED,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0DAA0D;IAC1D,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAID,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAA8B;gBAEjC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,kBAAuB;IAS1D;;;;;;;;;;;;;;OAcG;IACH,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,YAAY;IAwFhC;;;;;;;;;;OAUG;IACH,QAAQ,CACN,KAAK,EAAI,KAAK,EACd,KAAK,EAAI,GAAG,EAAE,EACd,OAAO,GAAE,MAAa,GACrB,YAAY,EAAE;IAkBjB;;;OAGG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAM1D;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAMvC,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,MAAM;IAKd,OAAO,CAAC,UAAU;CAkBnB"}