@linklabjs/core 0.1.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/README.md +411 -0
- package/package.json +48 -0
- package/src/api/DomainNode.ts +1433 -0
- package/src/api/Graph.ts +271 -0
- package/src/api/PathBuilder.ts +247 -0
- package/src/api/index.ts +15 -0
- package/src/api/loadGraph.ts +207 -0
- package/src/api/test-api.ts +153 -0
- package/src/api/test-domain.ts +119 -0
- package/src/api/types.ts +88 -0
- package/src/config/synonyms.json +28 -0
- package/src/core/EventBus.ts +187 -0
- package/src/core/GraphEvents.ts +153 -0
- package/src/core/PathFinder.ts +283 -0
- package/src/formatters/BaseFormatter.ts +17 -0
- package/src/graph/GraphAssembler.ts +50 -0
- package/src/graph/GraphCompiler.ts +412 -0
- package/src/graph/GraphExtractor.ts +191 -0
- package/src/graph/GraphOptimizer.ts +404 -0
- package/src/graph/GraphTrainer.ts +247 -0
- package/src/http/LinkBuilder.ts +244 -0
- package/src/http/TrailRequest.ts +48 -0
- package/src/http/example-netflix.ts +59 -0
- package/src/http/hateoas/README.md +87 -0
- package/src/http/index.ts +33 -0
- package/src/http/plugin.ts +360 -0
- package/src/index.ts +121 -0
- package/src/instrumentation/TelemetryShim.ts +172 -0
- package/src/navigation/NavigationEngine.ts +441 -0
- package/src/navigation/Resolver.ts +134 -0
- package/src/navigation/Scheduler.ts +136 -0
- package/src/navigation/Trail.ts +252 -0
- package/src/navigation/TrailParser.ts +207 -0
- package/src/navigation/index.ts +11 -0
- package/src/providers/MockProvider.ts +68 -0
- package/src/providers/PostgresProvider.ts +187 -0
- package/src/runtime/CompiledGraphEngine.ts +274 -0
- package/src/runtime/DataLoader.ts +236 -0
- package/src/runtime/Engine.ts +163 -0
- package/src/runtime/QueryEngine.ts +222 -0
- package/src/scenarios/test-metro-paris/config.json +6 -0
- package/src/scenarios/test-metro-paris/graph.json +16325 -0
- package/src/scenarios/test-metro-paris/queries.ts +152 -0
- package/src/scenarios/test-metro-paris/stack.json +1 -0
- package/src/scenarios/test-musicians/config.json +10 -0
- package/src/scenarios/test-musicians/graph.json +20 -0
- package/src/scenarios/test-musicians/stack.json +1 -0
- package/src/scenarios/test-netflix/MIGRATION.md +23 -0
- package/src/scenarios/test-netflix/README.md +138 -0
- package/src/scenarios/test-netflix/actions.ts +92 -0
- package/src/scenarios/test-netflix/config.json +6 -0
- package/src/scenarios/test-netflix/data/categories.json +1 -0
- package/src/scenarios/test-netflix/data/companies.json +1 -0
- package/src/scenarios/test-netflix/data/credits.json +19797 -0
- package/src/scenarios/test-netflix/data/departments.json +18 -0
- package/src/scenarios/test-netflix/data/jobs.json +142 -0
- package/src/scenarios/test-netflix/data/movies.json +3497 -0
- package/src/scenarios/test-netflix/data/people.json +1 -0
- package/src/scenarios/test-netflix/data/synonyms.json +8 -0
- package/src/scenarios/test-netflix/data/users.json +70 -0
- package/src/scenarios/test-netflix/graph.json +1017 -0
- package/src/scenarios/test-netflix/queries.ts +159 -0
- package/src/scenarios/test-netflix/stack.json +14 -0
- package/src/schema/GraphBuilder.ts +106 -0
- package/src/schema/JsonSchemaExtractor.ts +107 -0
- package/src/schema/SchemaAnalyzer.ts +175 -0
- package/src/schema/SchemaExtractor.ts +102 -0
- package/src/schema/SynonymResolver.ts +143 -0
- package/src/scripts/dictionary.json +796 -0
- package/src/scripts/graph.json +664 -0
- package/src/scripts/regenerate.ts +248 -0
- package/src/types/index.ts +506 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LinkLab Core Types
|
|
3
|
+
* * Base type definitions for the entire system
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================
|
|
7
|
+
// Graph Types
|
|
8
|
+
// ============================================================
|
|
9
|
+
|
|
10
|
+
export type NodeType = 'table' | 'view' | 'entity' | 'action'
|
|
11
|
+
|
|
12
|
+
export interface Column {
|
|
13
|
+
name: string
|
|
14
|
+
type: string
|
|
15
|
+
nullable?: boolean
|
|
16
|
+
primaryKey?: boolean
|
|
17
|
+
foreignKey?: boolean
|
|
18
|
+
defaultValue?: any
|
|
19
|
+
description?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface GraphNode {
|
|
23
|
+
id: string
|
|
24
|
+
type: string
|
|
25
|
+
name?: string
|
|
26
|
+
exposed?: boolean
|
|
27
|
+
[key: string]: any
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface GraphEdge {
|
|
31
|
+
from: string
|
|
32
|
+
to: string
|
|
33
|
+
weight: number
|
|
34
|
+
name?: string // Ajouté pour rel.label
|
|
35
|
+
via?: string // Ajouté pour stocker la colonne de jointure
|
|
36
|
+
fromCol?: string // Utilisé par le compilateur
|
|
37
|
+
toCol?: string // Utilisé par le compilateur
|
|
38
|
+
metadata?: {
|
|
39
|
+
condition?: string | Record<string, any>
|
|
40
|
+
semanticType?: string
|
|
41
|
+
[key: string]: any
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface Graph {
|
|
46
|
+
nodes: GraphNode[]
|
|
47
|
+
edges: GraphEdge[]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Pour le CompiledGraph (ce que le QueryEngine lira)
|
|
51
|
+
export interface RouteStep {
|
|
52
|
+
fromCol: string
|
|
53
|
+
toCol: string
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface RouteInfo {
|
|
57
|
+
from: string
|
|
58
|
+
to: string
|
|
59
|
+
primary: {
|
|
60
|
+
path: string[]
|
|
61
|
+
edges: RouteStep[] // 🌟 Ajouté ici
|
|
62
|
+
weight: number
|
|
63
|
+
joins: number
|
|
64
|
+
avgTime: number
|
|
65
|
+
}
|
|
66
|
+
fallbacks: Array<{
|
|
67
|
+
path: string[]
|
|
68
|
+
edges: RouteStep[] // 🌟 Ajouté ici
|
|
69
|
+
weight: number
|
|
70
|
+
joins: number
|
|
71
|
+
avgTime: number
|
|
72
|
+
}>
|
|
73
|
+
alternativesDiscarded: number
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface GraphMetadata {
|
|
77
|
+
version?: string
|
|
78
|
+
generatedAt?: string
|
|
79
|
+
database?: DatabaseInfo
|
|
80
|
+
[key: string]: any
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface DatabaseInfo {
|
|
84
|
+
name: string
|
|
85
|
+
type: 'postgresql' | 'mysql' | 'sqlite' | 'mongodb'
|
|
86
|
+
version?: string
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ============================================================
|
|
90
|
+
// Action & Registry Types
|
|
91
|
+
// ============================================================
|
|
92
|
+
|
|
93
|
+
export interface ActionDefinition {
|
|
94
|
+
id: string
|
|
95
|
+
description?: string
|
|
96
|
+
requiredParams: Column[] // Ce que l'action attend de la pile
|
|
97
|
+
provides?: string[] // Ce que l'action injecte après coup
|
|
98
|
+
handler: (context: any) => Promise<any>
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface ActionRegistry {
|
|
102
|
+
register(action: ActionDefinition): void
|
|
103
|
+
get(id: string): ActionDefinition | undefined
|
|
104
|
+
getAll(): ActionDefinition[]
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ============================================================
|
|
108
|
+
// Context & Engine Types
|
|
109
|
+
// ============================================================
|
|
110
|
+
|
|
111
|
+
export interface ContextLayer {
|
|
112
|
+
nodeId: string
|
|
113
|
+
timestamp: number
|
|
114
|
+
data: Record<string, any>
|
|
115
|
+
type: 'navigation' | 'action' | 'system'
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface EngineConfig {
|
|
119
|
+
cache?: CacheConfig
|
|
120
|
+
debug?: boolean
|
|
121
|
+
// Hooks pour l'intervention du développeur
|
|
122
|
+
onResolveContext?: (currentContext: any) => Awaitable<any>
|
|
123
|
+
onValidatePath?: (node: GraphNode, context: any) => Awaitable<boolean>
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ============================================================
|
|
127
|
+
// Path Types
|
|
128
|
+
// ============================================================
|
|
129
|
+
|
|
130
|
+
export type Path = string[]
|
|
131
|
+
|
|
132
|
+
export interface PathDetails {
|
|
133
|
+
path: Path
|
|
134
|
+
length: number
|
|
135
|
+
joins: number
|
|
136
|
+
weight: number
|
|
137
|
+
edges: GraphEdge[]
|
|
138
|
+
indirect?: boolean
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export interface PathMetrics {
|
|
142
|
+
path: Path
|
|
143
|
+
weight: number
|
|
144
|
+
joins: number
|
|
145
|
+
avgTime?: number
|
|
146
|
+
executions?: number
|
|
147
|
+
minTime?: number
|
|
148
|
+
maxTime?: number
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export type MetricsMap = Map<string, TrainingMetrics>
|
|
152
|
+
|
|
153
|
+
// ============================================================
|
|
154
|
+
// Provider Types
|
|
155
|
+
// ============================================================
|
|
156
|
+
|
|
157
|
+
export interface ProviderConfig {
|
|
158
|
+
host?: string
|
|
159
|
+
port?: number
|
|
160
|
+
database: string
|
|
161
|
+
user?: string
|
|
162
|
+
password?: string
|
|
163
|
+
connectionString?: string
|
|
164
|
+
mock?: boolean
|
|
165
|
+
[key: string]: any
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface Provider {
|
|
169
|
+
query<T = any>(sql: string, params?: any[]): Promise<T[]>
|
|
170
|
+
close(): Promise<void>
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ============================================================
|
|
174
|
+
// Compiled Graph Types
|
|
175
|
+
// ============================================================
|
|
176
|
+
|
|
177
|
+
export interface CompiledGraph {
|
|
178
|
+
version: string
|
|
179
|
+
compiledAt: string
|
|
180
|
+
config: CompilerConfig
|
|
181
|
+
nodes: GraphNode[]
|
|
182
|
+
routes: RouteInfo[]
|
|
183
|
+
stats: CompilationStats
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export interface CompilerConfig {
|
|
187
|
+
weightThreshold: number
|
|
188
|
+
minUsage?: number
|
|
189
|
+
keepFallbacks: boolean
|
|
190
|
+
maxFallbacks: number
|
|
191
|
+
expose?: ExposeConfig
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface CompilationStats {
|
|
195
|
+
totalPairs: number
|
|
196
|
+
routesCompiled: number
|
|
197
|
+
routesFiltered: number
|
|
198
|
+
compressionRatio: string
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ============================================================
|
|
202
|
+
// Training & Cache Types
|
|
203
|
+
// ============================================================
|
|
204
|
+
|
|
205
|
+
export interface UseCase {
|
|
206
|
+
description: string
|
|
207
|
+
from: string
|
|
208
|
+
to: string
|
|
209
|
+
sampleData?: Record<string, any>
|
|
210
|
+
expectedPath?: Path // Pour tes tests sémantiques
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface TrainingMetrics {
|
|
214
|
+
path: Path
|
|
215
|
+
executions: number
|
|
216
|
+
successes?: number
|
|
217
|
+
failures?: number
|
|
218
|
+
totalTime: number
|
|
219
|
+
avgTime: number
|
|
220
|
+
minTime: number
|
|
221
|
+
maxTime: number
|
|
222
|
+
used: boolean
|
|
223
|
+
failed?: boolean
|
|
224
|
+
error?: string
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export interface CacheConfig {
|
|
228
|
+
maxSize?: number
|
|
229
|
+
ttl?: number
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ============================================================
|
|
233
|
+
// Utility & Error Types
|
|
234
|
+
// ============================================================
|
|
235
|
+
|
|
236
|
+
export type Awaitable<T> = T | Promise<T>
|
|
237
|
+
|
|
238
|
+
export type ExposeConfig =
|
|
239
|
+
| 'all'
|
|
240
|
+
| 'none'
|
|
241
|
+
| { include: string[] }
|
|
242
|
+
| { exclude: string[] }
|
|
243
|
+
|
|
244
|
+
export class LinkLabError extends Error {
|
|
245
|
+
constructor(
|
|
246
|
+
message: string,
|
|
247
|
+
public code: string,
|
|
248
|
+
public details?: any
|
|
249
|
+
) {
|
|
250
|
+
super(message)
|
|
251
|
+
this.name = 'LinkLabError'
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export class ProviderError extends LinkLabError {
|
|
256
|
+
constructor(message: string, details?: any) {
|
|
257
|
+
super(message, 'PROVIDER_ERROR', details)
|
|
258
|
+
this.name = 'ProviderError'
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// --- Types pour la couche technique ---
|
|
263
|
+
|
|
264
|
+
export interface TechProperty {
|
|
265
|
+
name: string
|
|
266
|
+
type: string
|
|
267
|
+
isPK: boolean
|
|
268
|
+
isFK: boolean
|
|
269
|
+
references?: {
|
|
270
|
+
table: string
|
|
271
|
+
column: string
|
|
272
|
+
}
|
|
273
|
+
isIndexed: boolean
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export interface TechEntity {
|
|
277
|
+
name: string
|
|
278
|
+
properties: TechProperty[]
|
|
279
|
+
rowCount: number
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export interface TechnicalSchema {
|
|
283
|
+
source: {
|
|
284
|
+
type: string
|
|
285
|
+
name: string
|
|
286
|
+
generatedAt: string
|
|
287
|
+
}
|
|
288
|
+
entities: TechEntity[]
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// --- Types pour la couche d'Analyse ---
|
|
292
|
+
|
|
293
|
+
export interface AnalysisAdvice {
|
|
294
|
+
type: 'PERFORMANCE' | 'STRUCTURE' | 'VIRTUAL_RELATION'
|
|
295
|
+
level: 'INFO' | 'WARNING' | 'CRITICAL'
|
|
296
|
+
message: string
|
|
297
|
+
target: string // Le nom de la table ou table.colonne
|
|
298
|
+
action?: string // Commande suggérée ou flag pour le Builder
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export interface ImplicitRelation {
|
|
302
|
+
fromTable: string // Table source
|
|
303
|
+
column: string // Colonne *_id sans FK déclarée
|
|
304
|
+
guessedTable: string // Table cible résolue par SynonymResolver
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export interface AnalyzedSchema extends TechnicalSchema {
|
|
308
|
+
advices: AnalysisAdvice[]
|
|
309
|
+
weights: Record<string, number> // "table.colonne" -> poids numérique
|
|
310
|
+
implicitRelations: ImplicitRelation[] // FK implicites détectées par SchemaAnalyzer
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// --- Structure du Dictionnaire Final ---
|
|
314
|
+
|
|
315
|
+
export interface Dictionary {
|
|
316
|
+
tables: Table[]
|
|
317
|
+
relations: Relation[]
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export interface Table {
|
|
321
|
+
name: string
|
|
322
|
+
columns: string[]
|
|
323
|
+
rowCount: number
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export interface Relation {
|
|
327
|
+
from: string // Table source
|
|
328
|
+
to: string // Table destination
|
|
329
|
+
via: string // La clé technique (nom de la colonne ou table pivot)
|
|
330
|
+
type: 'physical' | 'physical_reverse' | 'semantic_view' | 'virtual'
|
|
331
|
+
weight: number // Calculé par l'Analyzer
|
|
332
|
+
label: string // Nom lisible (ex: "acting", "directing")
|
|
333
|
+
|
|
334
|
+
// Pour les vues sémantiques (le filtrage dynamique)
|
|
335
|
+
condition?: {
|
|
336
|
+
[column: string]: any // ex: { jobId: 2 }
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Pour le transport de données additionnelles (ex: nom du rôle dans 'options')
|
|
340
|
+
metadataField?: string
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Schema definitions for physical data discovery
|
|
345
|
+
*/
|
|
346
|
+
export interface ColumnSchema {
|
|
347
|
+
name: string
|
|
348
|
+
type: 'string' | 'number' | 'boolean' | 'date' | 'object' | 'array'
|
|
349
|
+
isNullable?: boolean
|
|
350
|
+
isPrimaryKey?: boolean
|
|
351
|
+
isForeignKey?: boolean
|
|
352
|
+
references?: {
|
|
353
|
+
table: string
|
|
354
|
+
column: string
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export interface TableSchema {
|
|
359
|
+
name: string
|
|
360
|
+
columns: ColumnSchema[]
|
|
361
|
+
rowCount?: number
|
|
362
|
+
fileSize?: number
|
|
363
|
+
filePath?: string // Chemin vers le JSON ou la table SQL
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export interface DatabaseSchema {
|
|
367
|
+
tables: TableSchema[]
|
|
368
|
+
relationships: SchemaRelationship[]
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export interface SchemaRelationship {
|
|
372
|
+
fromTable: string
|
|
373
|
+
fromColumn: string
|
|
374
|
+
toTable: string
|
|
375
|
+
toColumn: string
|
|
376
|
+
type: 'one-to-one' | 'one-to-many' | 'many-to-many'
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// ============================================================
|
|
380
|
+
// Navigation Engine Types (PATHFIND / NAVIGATE / SCHEDULE)
|
|
381
|
+
// ============================================================
|
|
382
|
+
|
|
383
|
+
export type EngineMode = 'PATHFIND' | 'NAVIGATE' | 'SCHEDULE'
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Frame : unité de navigation sur la stack.
|
|
387
|
+
* Représente un pointeur sémantique vers une entité,
|
|
388
|
+
* avec son état de résolution.
|
|
389
|
+
*/
|
|
390
|
+
export interface Frame {
|
|
391
|
+
entity: string
|
|
392
|
+
id?: any
|
|
393
|
+
state?: 'RESOLVED' | 'UNRESOLVED' | 'DEFERRED'
|
|
394
|
+
purpose?: string
|
|
395
|
+
intent?: Record<string, any>
|
|
396
|
+
data?: any
|
|
397
|
+
resolvedBy?: {
|
|
398
|
+
relation: string
|
|
399
|
+
via: string
|
|
400
|
+
filters?: FrameFilter[]
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export interface FrameFilter {
|
|
405
|
+
field: string
|
|
406
|
+
operator: 'equals' | 'contains' | 'gt' | 'lt' | 'exists'
|
|
407
|
+
value: any
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* PathQuery : paramètres pour le mode PATHFIND
|
|
412
|
+
*/
|
|
413
|
+
export interface PathQuery {
|
|
414
|
+
from: string
|
|
415
|
+
to: string
|
|
416
|
+
maxPaths?: number
|
|
417
|
+
minHops?: number // Nombre minimum d'étapes (ignore les chemins trop directs)
|
|
418
|
+
maxHops?: number
|
|
419
|
+
transferPenalty?: number // Pénalité en minutes par correspondance (0 = temps pur, 5 = confort)
|
|
420
|
+
via?: string[] // Types de relations autorisés ex: ['CREATED', 'SAMPLES', 'CREDITED']
|
|
421
|
+
preferences?: {
|
|
422
|
+
minimizeTransfers?: boolean
|
|
423
|
+
avoidEdges?: string[]
|
|
424
|
+
[key: string]: any
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* ScheduleAction : action pour le mode SCHEDULE.
|
|
430
|
+
* Différenciée de ActionDefinition (infrastructure) pour éviter
|
|
431
|
+
* tout conflit avec le registre d'actions techniques de V3.
|
|
432
|
+
*/
|
|
433
|
+
export interface ScheduleAction {
|
|
434
|
+
name: string
|
|
435
|
+
weight: number
|
|
436
|
+
when?: (stack: Frame[]) => boolean
|
|
437
|
+
execute: (stack: Frame[], graph: Graph) => Promise<Frame[]>
|
|
438
|
+
cooldown?: number
|
|
439
|
+
maxExecutions?: number
|
|
440
|
+
terminal?: boolean
|
|
441
|
+
onUse?: (stack: Frame[], result: NavigationResult) => void
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export interface ActionState {
|
|
445
|
+
cooldownUntil: number
|
|
446
|
+
executionCount: number
|
|
447
|
+
executed?: boolean
|
|
448
|
+
lastResult?: NavigationResult
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Config du NavigationEngine
|
|
453
|
+
*/
|
|
454
|
+
export interface NavigationEngineConfig {
|
|
455
|
+
mode: EngineMode
|
|
456
|
+
graph: Graph
|
|
457
|
+
trail?: import('../navigation/Trail.js').Trail // Trail existant à réutiliser
|
|
458
|
+
initialStack?: Frame[] // Ignoré si trail fourni
|
|
459
|
+
actions?: ScheduleAction[]
|
|
460
|
+
pathQuery?: PathQuery
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Résultat d'un step d'exécution
|
|
465
|
+
*/
|
|
466
|
+
export interface EngineStepResult {
|
|
467
|
+
time: number
|
|
468
|
+
mode: EngineMode
|
|
469
|
+
phase?: 'RESOLVE' | 'EXECUTE' | 'COMPLETE'
|
|
470
|
+
selectedAction?: string
|
|
471
|
+
resolvedCount?: number
|
|
472
|
+
unresolvedCount?: number
|
|
473
|
+
path?: NavigationPath
|
|
474
|
+
result?: NavigationResult
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Chemin trouvé par PATHFIND — riche en métadonnées
|
|
479
|
+
* pour les formatters (ligne, direction, correspondance)
|
|
480
|
+
*/
|
|
481
|
+
export interface NavigationPath {
|
|
482
|
+
nodes: string[]
|
|
483
|
+
edges: GraphEdge[]
|
|
484
|
+
totalWeight: number
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
export interface NavigationResult {
|
|
488
|
+
type: 'SUCCESS' | 'FAIL' | 'DEFER'
|
|
489
|
+
reason?: string
|
|
490
|
+
data?: any
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
// ============================================================
|
|
494
|
+
// Cache Stats (used by Engine LRU)
|
|
495
|
+
// ============================================================
|
|
496
|
+
|
|
497
|
+
export interface CacheStats {
|
|
498
|
+
entries: number
|
|
499
|
+
size: number
|
|
500
|
+
sizeFormatted: string
|
|
501
|
+
maxSize: number
|
|
502
|
+
usage: string
|
|
503
|
+
hits: number
|
|
504
|
+
misses: number
|
|
505
|
+
hitRate: string
|
|
506
|
+
}
|