@linklabjs/core 0.1.2 → 0.1.3

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 (63) hide show
  1. package/package.json +1 -1
  2. package/dist/scenarios/test-metro-paris/config.json +0 -6
  3. package/dist/scenarios/test-metro-paris/graph.json +0 -16325
  4. package/dist/scenarios/test-metro-paris/queries.d.ts +0 -22
  5. package/dist/scenarios/test-metro-paris/queries.d.ts.map +0 -1
  6. package/dist/scenarios/test-metro-paris/queries.js +0 -128
  7. package/dist/scenarios/test-metro-paris/queries.js.map +0 -1
  8. package/dist/scenarios/test-metro-paris/stack.json +0 -1
  9. package/dist/scenarios/test-musicians/config.json +0 -10
  10. package/dist/scenarios/test-musicians/graph.json +0 -20
  11. package/dist/scenarios/test-musicians/stack.json +0 -1
  12. package/dist/scenarios/test-netflix/actions.d.ts +0 -14
  13. package/dist/scenarios/test-netflix/actions.d.ts.map +0 -1
  14. package/dist/scenarios/test-netflix/actions.js +0 -86
  15. package/dist/scenarios/test-netflix/actions.js.map +0 -1
  16. package/dist/scenarios/test-netflix/config.json +0 -6
  17. package/dist/scenarios/test-netflix/data/categories.json +0 -1
  18. package/dist/scenarios/test-netflix/data/companies.json +0 -1
  19. package/dist/scenarios/test-netflix/data/credits.json +0 -19797
  20. package/dist/scenarios/test-netflix/data/departments.json +0 -18
  21. package/dist/scenarios/test-netflix/data/jobs.json +0 -142
  22. package/dist/scenarios/test-netflix/data/movies.json +0 -3497
  23. package/dist/scenarios/test-netflix/data/people.json +0 -1
  24. package/dist/scenarios/test-netflix/data/synonyms.json +0 -7
  25. package/dist/scenarios/test-netflix/data/users.json +0 -70
  26. package/dist/scenarios/test-netflix/graph.json +0 -1017
  27. package/dist/scenarios/test-netflix/queries.d.ts +0 -29
  28. package/dist/scenarios/test-netflix/queries.d.ts.map +0 -1
  29. package/dist/scenarios/test-netflix/queries.js +0 -134
  30. package/dist/scenarios/test-netflix/queries.js.map +0 -1
  31. package/dist/scenarios/test-netflix/stack.json +0 -14
  32. package/dist/scripts/dictionary.json +0 -796
  33. package/dist/scripts/graph.json +0 -664
  34. package/dist/scripts/regenerate.d.ts +0 -23
  35. package/dist/scripts/regenerate.d.ts.map +0 -1
  36. package/dist/scripts/regenerate.js +0 -206
  37. package/dist/scripts/regenerate.js.map +0 -1
  38. package/src/scenarios/test-metro-paris/config.json +0 -6
  39. package/src/scenarios/test-metro-paris/graph.json +0 -16325
  40. package/src/scenarios/test-metro-paris/queries.ts +0 -152
  41. package/src/scenarios/test-metro-paris/stack.json +0 -1
  42. package/src/scenarios/test-musicians/config.json +0 -10
  43. package/src/scenarios/test-musicians/graph.json +0 -20
  44. package/src/scenarios/test-musicians/stack.json +0 -1
  45. package/src/scenarios/test-netflix/MIGRATION.md +0 -23
  46. package/src/scenarios/test-netflix/README.md +0 -138
  47. package/src/scenarios/test-netflix/actions.ts +0 -92
  48. package/src/scenarios/test-netflix/config.json +0 -6
  49. package/src/scenarios/test-netflix/data/categories.json +0 -1
  50. package/src/scenarios/test-netflix/data/companies.json +0 -1
  51. package/src/scenarios/test-netflix/data/credits.json +0 -19797
  52. package/src/scenarios/test-netflix/data/departments.json +0 -18
  53. package/src/scenarios/test-netflix/data/jobs.json +0 -142
  54. package/src/scenarios/test-netflix/data/movies.json +0 -3497
  55. package/src/scenarios/test-netflix/data/people.json +0 -1
  56. package/src/scenarios/test-netflix/data/synonyms.json +0 -8
  57. package/src/scenarios/test-netflix/data/users.json +0 -70
  58. package/src/scenarios/test-netflix/graph.json +0 -1017
  59. package/src/scenarios/test-netflix/queries.ts +0 -159
  60. package/src/scenarios/test-netflix/stack.json +0 -14
  61. package/src/scripts/dictionary.json +0 -796
  62. package/src/scripts/graph.json +0 -664
  63. package/src/scripts/regenerate.ts +0 -248
@@ -1,248 +0,0 @@
1
- /**
2
- * regenerate.ts — Script de régénération des graphes compilés
3
- *
4
- * Usage :
5
- * npx tsx regenerate.ts netflix
6
- * npx tsx regenerate.ts dvdrental --pg host=localhost user=postgres password=secret
7
- * npx tsx regenerate.ts all
8
- *
9
- * Régénère compiled-graph.json pour chaque scénario.
10
- * Bumpe automatiquement la version dans le fichier produit.
11
- *
12
- * Versioning :
13
- * - Graphes générés (netflix, dvdrental) : version dans compiled-graph.json
14
- * format : MAJOR.MINOR.PATCH ex: 2.0.0
15
- * MAJOR = version du GraphCompiler (structure breaking)
16
- * MINOR = changement de schéma (nouvelles tables/relations)
17
- * PATCH = recompilation (nouveaux poids, métriques)
18
- *
19
- * - Graphes manuels (metro, musicians) : version dans raw-graph.json + compiled
20
- * Patch manuel dans raw-graph.json, puis npx tsx regenerate.ts metro
21
- */
22
-
23
- import * as fs from 'fs'
24
- import * as path from 'path'
25
- import { fileURLToPath } from 'url'
26
- import { dirname } from 'path'
27
-
28
- import { JsonSchemaExtractor } from '../schema/JsonSchemaExtractor.js'
29
- import { SchemaAnalyzer } from '../schema/SchemaAnalyzer.js'
30
- import { GraphBuilder } from '../schema/GraphBuilder.js'
31
- import { GraphAssembler } from '../graph/GraphAssembler.js'
32
- import { GraphCompiler } from '../graph/GraphCompiler.js'
33
- import { PathFinder } from '../core/PathFinder.js'
34
- import type { MetricsMap, TrainingMetrics, UseCase } from '../types/index.js'
35
-
36
- const __filename = fileURLToPath(import.meta.url)
37
- const __dirname = dirname(__filename)
38
- const ROOT = path.join(__dirname, '..', 'examples')
39
- const CONFIG_DIR = path.join(__dirname, '..', '..', 'config')
40
-
41
- // ── Helpers ───────────────────────────────────────────────────────────────────
42
-
43
- function save(filepath: string, data: unknown) {
44
- fs.writeFileSync(filepath, JSON.stringify(data, null, 2))
45
- const kb = (fs.statSync(filepath).size / 1024).toFixed(1)
46
- console.log(` 💾 ${path.basename(filepath).padEnd(25)} ${kb} KB`)
47
- }
48
-
49
- function bumpPatch(current: string): string {
50
- const parts = current.split('.').map(Number)
51
- if (parts.length !== 3 || parts.some(isNaN)) return '2.0.0'
52
- parts[2]++
53
- return parts.join('.')
54
- }
55
-
56
- function readCurrentVersion(compiledPath: string): string {
57
- try {
58
- const c = JSON.parse(fs.readFileSync(compiledPath, 'utf-8'))
59
- return c.version ?? '2.0.0'
60
- } catch {
61
- return '2.0.0'
62
- }
63
- }
64
-
65
- // ── Entraînement local (sans provider externe) ────────────────────────────────
66
-
67
- function trainLocal(graph: any, useCases: UseCase[]): MetricsMap {
68
- const metrics: MetricsMap = new Map<string, TrainingMetrics>()
69
- const finder = new PathFinder(graph)
70
-
71
- for (const uc of useCases) {
72
- const paths = finder.findAllPaths(uc.from, uc.to)
73
- for (const p of paths) {
74
- metrics.set(p.join('→'), {
75
- path: p,
76
- executions: 10,
77
- successes: 10,
78
- totalTime: 100,
79
- avgTime: 10,
80
- minTime: 8,
81
- maxTime: 12,
82
- used: true,
83
- failed: false
84
- })
85
- }
86
- }
87
- return metrics
88
- }
89
-
90
- // ── Pipeline JSON (netflix, cinema, etc.) ─────────────────────────────────────
91
-
92
- async function regenerateFromJSON(scenario: string) {
93
- const dir = path.join(ROOT, scenario)
94
- const dataDir = path.join(dir, 'data')
95
- const compiledOut = path.join(dir, 'compiled-graph.json')
96
-
97
- if (!fs.existsSync(dataDir)) {
98
- console.error(` ❌ data/ not found: ${dataDir}`)
99
- return
100
- }
101
-
102
- console.log(`\n🔄 ${scenario} — pipeline JSON`)
103
- console.log('─'.repeat(50))
104
-
105
- // Step 1 : Extraction
106
- const extractor = new JsonSchemaExtractor(dataDir)
107
- const techSchema = await extractor.extract()
108
- save(path.join(dir, 'schema.json'), techSchema)
109
-
110
- // Step 2 : Analyse
111
- const analyzer = new SchemaAnalyzer(CONFIG_DIR, dataDir)
112
- const analyzedSchema = analyzer.analyze(techSchema)
113
- save(path.join(dir, 'analyzed-schema.json'), analyzedSchema)
114
-
115
- // Step 3 : Dictionnaire
116
- const builder = new GraphBuilder()
117
- const dictionary = builder.build(analyzedSchema, dataDir)
118
- save(path.join(dir, 'dictionary.json'), dictionary)
119
-
120
- // Step 4 : Graphe brut
121
- const assembler = new GraphAssembler()
122
- const rawGraph = assembler.assemble(dictionary)
123
- save(path.join(dir, 'raw-graph.json'), rawGraph)
124
- console.log(` 📊 ${rawGraph.nodes.length} nœuds · ${rawGraph.edges.length} arêtes`)
125
-
126
- // Step 5 : Use cases (lire depuis use-cases.json si présent, sinon défaut)
127
- const ucFile = path.join(dir, 'use-cases.json')
128
- const useCases: UseCase[] = fs.existsSync(ucFile)
129
- ? JSON.parse(fs.readFileSync(ucFile, 'utf-8'))
130
- : buildDefaultUseCases(rawGraph)
131
-
132
- const metrics = trainLocal(rawGraph, useCases)
133
- save(path.join(dir, 'metrics.json'), Object.fromEntries(metrics))
134
-
135
- // Step 6 : Compilation
136
- const prevVersion = readCurrentVersion(compiledOut)
137
- const newVersion = bumpPatch(prevVersion)
138
-
139
- const compiler = new GraphCompiler({ weightThreshold: 1000, keepFallbacks: true })
140
- const compiledGraph = compiler.compile(rawGraph, metrics)
141
- ;(compiledGraph as any).version = newVersion
142
- ;(compiledGraph as any).scenario = scenario
143
-
144
- save(compiledOut, compiledGraph)
145
-
146
- const stats = GraphCompiler.getStats(compiledGraph)
147
- console.log(
148
- `\n ✅ ${stats.totalRoutes} routes (${stats.physical} physical · ${stats.semantic} semantic)`
149
- )
150
- console.log(` 📌 version: ${prevVersion} → ${newVersion}`)
151
- }
152
-
153
- // ── Pipeline manuel (metro, musicians) ───────────────────────────────────────
154
- // raw-graph.json édité à la main → on recompile seulement
155
-
156
- async function recompileManual(scenario: string) {
157
- const dir = path.join(ROOT, scenario)
158
- const rawPath = path.join(dir, 'raw-graph.json')
159
- const compiledOut = path.join(dir, 'compiled-graph.json')
160
-
161
- if (!fs.existsSync(rawPath)) {
162
- console.error(` ❌ raw-graph.json not found: ${rawPath}`)
163
- return
164
- }
165
-
166
- console.log(`\n🔄 ${scenario} — recompile manual graph`)
167
- console.log('─'.repeat(50))
168
-
169
- const rawGraph = JSON.parse(fs.readFileSync(rawPath, 'utf-8'))
170
-
171
- const ucFile = path.join(dir, 'use-cases.json')
172
- const useCases: UseCase[] = fs.existsSync(ucFile)
173
- ? JSON.parse(fs.readFileSync(ucFile, 'utf-8'))
174
- : buildDefaultUseCases(rawGraph)
175
-
176
- const metrics = trainLocal(rawGraph, useCases)
177
-
178
- const prevVersion = readCurrentVersion(compiledOut)
179
- const newVersion = bumpPatch(prevVersion)
180
-
181
- const compiler = new GraphCompiler({ weightThreshold: 1000, keepFallbacks: true })
182
- const compiledGraph = compiler.compile(rawGraph, metrics)
183
- ;(compiledGraph as any).version = newVersion
184
- ;(compiledGraph as any).scenario = scenario
185
-
186
- save(compiledOut, compiledGraph)
187
-
188
- const stats = GraphCompiler.getStats(compiledGraph)
189
- console.log(
190
- ` ✅ ${stats.totalRoutes} routes (${stats.physical} physical · ${stats.semantic} semantic)`
191
- )
192
- console.log(` 📌 version: ${prevVersion} → ${newVersion}`)
193
- }
194
-
195
- // ── Déterminer le type de scénario ────────────────────────────────────────────
196
-
197
- function scenarioType(scenario: string): 'json' | 'manual' | 'unknown' {
198
- const dir = path.join(ROOT, scenario)
199
- if (fs.existsSync(path.join(dir, 'data'))) return 'json'
200
- if (fs.existsSync(path.join(dir, 'raw-graph.json'))) return 'manual'
201
- return 'unknown'
202
- }
203
-
204
- function buildDefaultUseCases(graph: any): UseCase[] {
205
- // Générer des use cases par défaut depuis les nœuds du graphe
206
- const nodes = graph.nodes.map((n: any) => n.id as string)
207
- const cases: UseCase[] = []
208
- for (let i = 0; i < Math.min(nodes.length, 4); i++) {
209
- for (let j = 0; j < Math.min(nodes.length, 4); j++) {
210
- if (i !== j)
211
- cases.push({ from: nodes[i], to: nodes[j], description: `${nodes[i]}→${nodes[j]}` })
212
- }
213
- }
214
- return cases
215
- }
216
-
217
- // ── Main ──────────────────────────────────────────────────────────────────────
218
-
219
- async function main() {
220
- const args = process.argv.slice(2)
221
- const scenarios =
222
- args[0] === 'all'
223
- ? fs.readdirSync(ROOT).filter(d => fs.statSync(path.join(ROOT, d)).isDirectory())
224
- : args.filter(a => !a.startsWith('--'))
225
-
226
- if (!scenarios.length) {
227
- console.log('Usage: npx tsx regenerate.ts <scenario|all> [--pg ...]')
228
- console.log('Examples:')
229
- console.log(' npx tsx regenerate.ts netflix')
230
- console.log(' npx tsx regenerate.ts metro musicians')
231
- console.log(' npx tsx regenerate.ts all')
232
- process.exit(0)
233
- }
234
-
235
- for (const scenario of scenarios) {
236
- const type = scenarioType(scenario)
237
- if (type === 'json') await regenerateFromJSON(scenario)
238
- else if (type === 'manual') await recompileManual(scenario)
239
- else console.warn(` ⚠️ ${scenario}: unknown scenario type (no data/ nor raw-graph.json)`)
240
- }
241
-
242
- console.log('\n✅ Done\n')
243
- }
244
-
245
- main().catch(err => {
246
- console.error('❌', err)
247
- process.exit(1)
248
- })