@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,107 @@
1
+ /**
2
+ * Scheduler - Exécution d'actions par priorité (mode SCHEDULE)
3
+ *
4
+ * À chaque step :
5
+ * 1. Filtre les actions disponibles (condition when + cooldown + terminal)
6
+ * 2. Sélectionne la plus prioritaire (weight le plus élevé)
7
+ * 3. L'exécute et met à jour l'état interne
8
+ *
9
+ * C'est le cœur du moteur d'agent : une boucle de décision
10
+ * déterministe basée sur les poids et l'état de la stack.
11
+ */
12
+ export class Scheduler {
13
+ actions;
14
+ graph;
15
+ actionStates;
16
+ constructor(actions, graph) {
17
+ this.actions = actions;
18
+ this.graph = graph;
19
+ // Initialise l'état de chaque action
20
+ this.actionStates = new Map(actions.map(a => [
21
+ a.name,
22
+ { cooldownUntil: 0, executionCount: 0, executed: false }
23
+ ]));
24
+ }
25
+ /**
26
+ * Exécute un step du scheduler.
27
+ * Retourne null si aucune action n'est disponible (terminaison naturelle).
28
+ */
29
+ async step(time, stack) {
30
+ const available = this.getAvailableActions(time, stack);
31
+ if (available.length === 0)
32
+ return null;
33
+ // Sélection déterministe : weight le plus élevé
34
+ const selected = available.reduce((best, action) => action.weight > best.weight ? action : best);
35
+ console.log(` ⚙️ [Scheduler t=${time}] → ${selected.name} (weight: ${selected.weight})`);
36
+ let result;
37
+ let updatedStack = stack;
38
+ try {
39
+ updatedStack = await selected.execute(stack, this.graph);
40
+ result = { type: 'SUCCESS', data: updatedStack };
41
+ }
42
+ catch (err) {
43
+ result = {
44
+ type: 'FAIL',
45
+ reason: err instanceof Error ? err.message : String(err)
46
+ };
47
+ console.error(` ❌ [Scheduler] Action échouée: ${selected.name}`, err);
48
+ }
49
+ // Callback optionnel (analytics, logging externe...)
50
+ if (selected.onUse) {
51
+ try {
52
+ selected.onUse(stack, result);
53
+ }
54
+ catch {
55
+ // Silencieux — le callback ne doit pas planter le scheduler
56
+ }
57
+ }
58
+ // Mise à jour de l'état de l'action
59
+ this.updateState(selected, result, time);
60
+ return {
61
+ selectedAction: selected.name,
62
+ result,
63
+ updatedStack: result.type === 'SUCCESS' ? updatedStack : stack
64
+ };
65
+ }
66
+ /**
67
+ * Retourne les actions disponibles à un instant t pour une stack donnée.
68
+ * Filtre : terminal déjà exécuté, cooldown, maxExecutions, condition when().
69
+ */
70
+ getAvailableActions(time, stack) {
71
+ return this.actions.filter(action => {
72
+ const state = this.actionStates.get(action.name);
73
+ // Action terminale déjà exécutée
74
+ if (action.terminal && state.executed)
75
+ return false;
76
+ // En cooldown
77
+ if (state.cooldownUntil > time)
78
+ return false;
79
+ // Limite d'exécutions atteinte
80
+ if (action.maxExecutions !== undefined && state.executionCount >= action.maxExecutions) {
81
+ return false;
82
+ }
83
+ // Condition métier
84
+ if (!action.when)
85
+ return true;
86
+ try {
87
+ return action.when(stack);
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ });
93
+ }
94
+ updateState(action, result, time) {
95
+ const current = this.actionStates.get(action.name);
96
+ this.actionStates.set(action.name, {
97
+ cooldownUntil: result.type === 'DEFER' ? time + (action.cooldown ?? 0) : 0,
98
+ executionCount: current.executionCount + 1,
99
+ executed: action.terminal ? true : current.executed,
100
+ lastResult: result
101
+ });
102
+ }
103
+ getActionState(name) {
104
+ return this.actionStates.get(name);
105
+ }
106
+ }
107
+ //# sourceMappingURL=Scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scheduler.js","sourceRoot":"","sources":["../../src/navigation/Scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Trail — Contexte de navigation vivant
3
+ *
4
+ * Trois niveaux de contexte, trois durées de vie :
5
+ *
6
+ * global — vit aussi longtemps que l'instance LinkLab
7
+ * config, feature flags, métriques globales
8
+ *
9
+ * user — vit le temps d'une session
10
+ * userId, permissions, préférences, historique récent
11
+ *
12
+ * frames — vit le temps d'une navigation
13
+ * le chemin parcouru, position courante
14
+ *
15
+ * Deux niveaux d'API :
16
+ *
17
+ * Bas niveau — trail.push(frame), trail.pop(), trail.compact()
18
+ * fondation sur laquelle tout repose
19
+ *
20
+ * Haut niveau — API fluente, construite sur push()
21
+ * cinema.people('Nolan').movies
22
+ *
23
+ * Contrat de sérialisation :
24
+ * global et user ne contiennent que des données — jamais de fonctions.
25
+ * Un Trail sérialisé peut être rejoué exactement.
26
+ */
27
+ import type { Frame } from '../types/index.js';
28
+ export interface TrailInit {
29
+ global?: Record<string, any>;
30
+ user?: Record<string, any>;
31
+ frames?: Frame[];
32
+ }
33
+ /** Format de sérialisation — versionné pour les migrations futures */
34
+ export interface SerializedTrail {
35
+ v: number;
36
+ global: Record<string, any>;
37
+ user: Record<string, any>;
38
+ frames: Frame[];
39
+ savedAt: string;
40
+ }
41
+ export declare class Trail {
42
+ /** Contexte global — long terme */
43
+ readonly global: Record<string, any>;
44
+ /** Contexte utilisateur — session */
45
+ readonly user: Record<string, any>;
46
+ /** Frames de navigation — readonly depuis l'extérieur */
47
+ private _frames;
48
+ private constructor();
49
+ /** Crée un Trail vierge, avec contextes optionnels */
50
+ static create(init?: TrailInit): Trail;
51
+ /** Restaure un Trail depuis sa forme sérialisée */
52
+ static from(serialized: string | SerializedTrail): Trail;
53
+ /** Toutes les frames — tableau immuable depuis l'extérieur */
54
+ get frames(): readonly Frame[];
55
+ /** Dernière frame — position courante */
56
+ get current(): Frame | undefined;
57
+ /** Nombre de frames */
58
+ get depth(): number;
59
+ /** Vrai si toutes les frames sont résolues */
60
+ get isFullyResolved(): boolean;
61
+ /** Frames non résolues */
62
+ get unresolved(): Frame[];
63
+ /**
64
+ * Pousse une frame sur le Trail.
65
+ * Retourne this pour le chaînage.
66
+ *
67
+ * Si state n'est pas précisé :
68
+ * - id fourni → RESOLVED
69
+ * - id absent → UNRESOLVED
70
+ */
71
+ push(frame: Frame): this;
72
+ /**
73
+ * Retire et retourne la dernière frame.
74
+ * Retourne undefined si le Trail est vide.
75
+ */
76
+ pop(): Frame | undefined;
77
+ /**
78
+ * Met à jour une frame existante par index ou par entity.
79
+ * Réservé à LinkLab — permet au moteur de synchroniser les frames résolues.
80
+ *
81
+ * @param entity - L'entité de la frame à mettre à jour
82
+ * @param updated - Les nouvelles valeurs à merger
83
+ */
84
+ updateFrame(entity: string, updated: Partial<Frame>): boolean;
85
+ /**
86
+ * Compacte le Trail — supprime les frames non-discriminantes
87
+ * en conservant uniquement les frames qui portent un id
88
+ * ou qui sont la position courante.
89
+ *
90
+ * Exemple :
91
+ * [cinema][people(Nolan)][movies(Interstellar)][actors]
92
+ * → [people(Nolan)][movies(Interstellar)][actors]
93
+ *
94
+ * Note : réservé à LinkLab — appelé par le moteur, pas par les hooks.
95
+ */
96
+ compact(): this;
97
+ /**
98
+ * Retourne la frame à l'index donné (0 = première).
99
+ * Accepte les index négatifs (-1 = dernière).
100
+ */
101
+ at(index: number): Frame | undefined;
102
+ /**
103
+ * Retourne la dernière frame dont l'entity correspond.
104
+ */
105
+ find(entity: string): Frame | undefined;
106
+ /**
107
+ * Retourne un Trail tronqué jusqu'à l'index donné (non inclus).
108
+ * Utile pour le replay partiel.
109
+ */
110
+ slice(end: number): Trail;
111
+ /**
112
+ * Sérialise le Trail en JSON.
113
+ * global et user ne doivent contenir que des données — les fonctions
114
+ * sont silencieusement ignorées par JSON.stringify.
115
+ */
116
+ serialize(): string;
117
+ toJSON(): SerializedTrail;
118
+ /**
119
+ * Deep copy — utile pour le replay ou les tests.
120
+ * Le clone est indépendant — modifier l'un ne modifie pas l'autre.
121
+ */
122
+ clone(): Trail;
123
+ /**
124
+ * Représentation lisible du Trail courant.
125
+ * ex: [people(Nolan)] → [movies(Interstellar)] → [actors?]
126
+ */
127
+ toString(): string;
128
+ }
129
+ //# sourceMappingURL=Trail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Trail.d.ts","sourceRoot":"","sources":["../../src/navigation/Trail.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAI9C,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,IAAI,CAAC,EAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,MAAM,CAAC,EAAE,KAAK,EAAE,CAAA;CACjB;AAED,sEAAsE;AACtE,MAAM,WAAW,eAAe;IAC9B,CAAC,EAAQ,MAAM,CAAA;IACf,MAAM,EAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,IAAI,EAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,MAAM,EAAG,KAAK,EAAE,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;CAChB;AAID,qBAAa,KAAK;IAChB,mCAAmC;IACnC,SAAgB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAE3C,qCAAqC;IACrC,SAAgB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEzC,yDAAyD;IACzD,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO;IAQP,sDAAsD;IACtD,MAAM,CAAC,MAAM,CAAC,IAAI,GAAE,SAAc,GAAG,KAAK;IAI1C,mDAAmD;IACnD,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,KAAK;IAkBxD,8DAA8D;IAC9D,IAAI,MAAM,IAAI,SAAS,KAAK,EAAE,CAE7B;IAED,yCAAyC;IACzC,IAAI,OAAO,IAAI,KAAK,GAAG,SAAS,CAE/B;IAED,uBAAuB;IACvB,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,8CAA8C;IAC9C,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,0BAA0B;IAC1B,IAAI,UAAU,IAAI,KAAK,EAAE,CAExB;IAID;;;;;;;OAOG;IACH,IAAI,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IASxB;;;OAGG;IACH,GAAG,IAAI,KAAK,GAAG,SAAS;IAIxB;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,OAAO;IAS7D;;;;;;;;;;OAUG;IACH,OAAO,IAAI,IAAI;IAQf;;;OAGG;IACH,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAKpC;;OAEG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAIvC;;;OAGG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK;IAUzB;;;;OAIG;IACH,SAAS,IAAI,MAAM;IAInB,MAAM,IAAI,eAAe;IAUzB;;;OAGG;IACH,KAAK,IAAI,KAAK;IAMd;;;OAGG;IACH,QAAQ,IAAI,MAAM;CAWnB"}
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Trail — Contexte de navigation vivant
3
+ *
4
+ * Trois niveaux de contexte, trois durées de vie :
5
+ *
6
+ * global — vit aussi longtemps que l'instance LinkLab
7
+ * config, feature flags, métriques globales
8
+ *
9
+ * user — vit le temps d'une session
10
+ * userId, permissions, préférences, historique récent
11
+ *
12
+ * frames — vit le temps d'une navigation
13
+ * le chemin parcouru, position courante
14
+ *
15
+ * Deux niveaux d'API :
16
+ *
17
+ * Bas niveau — trail.push(frame), trail.pop(), trail.compact()
18
+ * fondation sur laquelle tout repose
19
+ *
20
+ * Haut niveau — API fluente, construite sur push()
21
+ * cinema.people('Nolan').movies
22
+ *
23
+ * Contrat de sérialisation :
24
+ * global et user ne contiennent que des données — jamais de fonctions.
25
+ * Un Trail sérialisé peut être rejoué exactement.
26
+ */
27
+ // ── Trail ─────────────────────────────────────────────────────
28
+ export class Trail {
29
+ /** Contexte global — long terme */
30
+ global;
31
+ /** Contexte utilisateur — session */
32
+ user;
33
+ /** Frames de navigation — readonly depuis l'extérieur */
34
+ _frames;
35
+ constructor(init = {}) {
36
+ this.global = init.global ?? {};
37
+ this.user = init.user ?? {};
38
+ this._frames = init.frames ? init.frames.map(f => ({ ...f })) : [];
39
+ }
40
+ // ── Factories ──────────────────────────────────────────────
41
+ /** Crée un Trail vierge, avec contextes optionnels */
42
+ static create(init = {}) {
43
+ return new Trail(init);
44
+ }
45
+ /** Restaure un Trail depuis sa forme sérialisée */
46
+ static from(serialized) {
47
+ const data = typeof serialized === 'string'
48
+ ? JSON.parse(serialized)
49
+ : serialized;
50
+ if (data.v !== 1) {
51
+ throw new Error(`Trail.from: version ${data.v} non supportée`);
52
+ }
53
+ return new Trail({
54
+ global: data.global ?? {},
55
+ user: data.user ?? {},
56
+ frames: data.frames ?? [],
57
+ });
58
+ }
59
+ // ── Accesseurs frames ──────────────────────────────────────
60
+ /** Toutes les frames — tableau immuable depuis l'extérieur */
61
+ get frames() {
62
+ return this._frames;
63
+ }
64
+ /** Dernière frame — position courante */
65
+ get current() {
66
+ return this._frames[this._frames.length - 1];
67
+ }
68
+ /** Nombre de frames */
69
+ get depth() {
70
+ return this._frames.length;
71
+ }
72
+ /** Vrai si toutes les frames sont résolues */
73
+ get isFullyResolved() {
74
+ return this._frames.every(f => f.state === 'RESOLVED');
75
+ }
76
+ /** Frames non résolues */
77
+ get unresolved() {
78
+ return this._frames.filter(f => f.state === 'UNRESOLVED');
79
+ }
80
+ // ── API bas niveau ─────────────────────────────────────────
81
+ /**
82
+ * Pousse une frame sur le Trail.
83
+ * Retourne this pour le chaînage.
84
+ *
85
+ * Si state n'est pas précisé :
86
+ * - id fourni → RESOLVED
87
+ * - id absent → UNRESOLVED
88
+ */
89
+ push(frame) {
90
+ const normalized = {
91
+ ...frame,
92
+ state: frame.state ?? (frame.id !== undefined ? 'RESOLVED' : 'UNRESOLVED'),
93
+ };
94
+ this._frames.push(normalized);
95
+ return this;
96
+ }
97
+ /**
98
+ * Retire et retourne la dernière frame.
99
+ * Retourne undefined si le Trail est vide.
100
+ */
101
+ pop() {
102
+ return this._frames.pop();
103
+ }
104
+ /**
105
+ * Met à jour une frame existante par index ou par entity.
106
+ * Réservé à LinkLab — permet au moteur de synchroniser les frames résolues.
107
+ *
108
+ * @param entity - L'entité de la frame à mettre à jour
109
+ * @param updated - Les nouvelles valeurs à merger
110
+ */
111
+ updateFrame(entity, updated) {
112
+ const idx = this._frames.findIndex(f => f.entity === entity && f.state === 'UNRESOLVED');
113
+ if (idx === -1)
114
+ return false;
115
+ this._frames[idx] = { ...this._frames[idx], ...updated };
116
+ return true;
117
+ }
118
+ /**
119
+ * Compacte le Trail — supprime les frames non-discriminantes
120
+ * en conservant uniquement les frames qui portent un id
121
+ * ou qui sont la position courante.
122
+ *
123
+ * Exemple :
124
+ * [cinema][people(Nolan)][movies(Interstellar)][actors]
125
+ * → [people(Nolan)][movies(Interstellar)][actors]
126
+ *
127
+ * Note : réservé à LinkLab — appelé par le moteur, pas par les hooks.
128
+ */
129
+ compact() {
130
+ const last = this._frames.length - 1;
131
+ this._frames = this._frames.filter((f, i) => i === last || f.id !== undefined);
132
+ return this;
133
+ }
134
+ /**
135
+ * Retourne la frame à l'index donné (0 = première).
136
+ * Accepte les index négatifs (-1 = dernière).
137
+ */
138
+ at(index) {
139
+ if (index < 0)
140
+ index = this._frames.length + index;
141
+ return this._frames[index];
142
+ }
143
+ /**
144
+ * Retourne la dernière frame dont l'entity correspond.
145
+ */
146
+ find(entity) {
147
+ return [...this._frames].reverse().find(f => f.entity === entity);
148
+ }
149
+ /**
150
+ * Retourne un Trail tronqué jusqu'à l'index donné (non inclus).
151
+ * Utile pour le replay partiel.
152
+ */
153
+ slice(end) {
154
+ return new Trail({
155
+ global: { ...this.global },
156
+ user: { ...this.user },
157
+ frames: this._frames.slice(0, end),
158
+ });
159
+ }
160
+ // ── Sérialisation ──────────────────────────────────────────
161
+ /**
162
+ * Sérialise le Trail en JSON.
163
+ * global et user ne doivent contenir que des données — les fonctions
164
+ * sont silencieusement ignorées par JSON.stringify.
165
+ */
166
+ serialize() {
167
+ return JSON.stringify(this.toJSON());
168
+ }
169
+ toJSON() {
170
+ return {
171
+ v: 1,
172
+ global: this.global,
173
+ user: this.user,
174
+ frames: [...this._frames],
175
+ savedAt: new Date().toISOString(),
176
+ };
177
+ }
178
+ /**
179
+ * Deep copy — utile pour le replay ou les tests.
180
+ * Le clone est indépendant — modifier l'un ne modifie pas l'autre.
181
+ */
182
+ clone() {
183
+ return Trail.from(this.toJSON());
184
+ }
185
+ // ── Debug ──────────────────────────────────────────────────
186
+ /**
187
+ * Représentation lisible du Trail courant.
188
+ * ex: [people(Nolan)] → [movies(Interstellar)] → [actors?]
189
+ */
190
+ toString() {
191
+ if (this._frames.length === 0)
192
+ return '(trail vide)';
193
+ return this._frames
194
+ .map(f => {
195
+ const id = f.id !== undefined ? `(${f.id})` : '';
196
+ const state = f.state === 'UNRESOLVED' ? '?' : f.state === 'DEFERRED' ? '…' : '';
197
+ return `[${f.entity}${id}${state}]`;
198
+ })
199
+ .join(' → ');
200
+ }
201
+ }
202
+ //# sourceMappingURL=Trail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Trail.js","sourceRoot":"","sources":["../../src/navigation/Trail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * TrailParser — Désérialise des représentations externes vers un Trail
3
+ *
4
+ * Trois sources supportées :
5
+ *
6
+ * URL path → /cinema/people/Nolan/movies/Interstellar/actors
7
+ * URL fluent → cinema.people(Nolan).movies(Interstellar).actors
8
+ * JSON → SerializedTrail (via Trail.from)
9
+ *
10
+ * Le parser est stateless — toutes les méthodes sont statiques.
11
+ * Il ne valide pas les entités contre le graphe — c'est le rôle du moteur.
12
+ */
13
+ import { Trail } from './Trail.js';
14
+ export declare class TrailParser {
15
+ /**
16
+ * Parse un path HTTP en Trail.
17
+ *
18
+ * Convention :
19
+ * /entity → Frame(entity, UNRESOLVED)
20
+ * /entity/id → Frame(entity, id, RESOLVED)
21
+ * /entity/id/other → Frame(entity, id) + Frame(other, UNRESOLVED)
22
+ *
23
+ * Exemples :
24
+ * /people → [people?]
25
+ * /people/Nolan → [people(Nolan)]
26
+ * /people/Nolan/movies → [people(Nolan)] → [movies?]
27
+ * /people/Nolan/movies/2 → [people(Nolan)] → [movies(2)]
28
+ * /cinema/people/Nolan/movies → [cinema] → [people(Nolan)] → [movies?]
29
+ *
30
+ * @param path - URL path, avec ou sans slash initial
31
+ * @param init - Contextes global/user à injecter
32
+ */
33
+ static fromPath(path: string, init?: {
34
+ global?: Record<string, any>;
35
+ user?: Record<string, any>;
36
+ }): Trail;
37
+ /**
38
+ * Parse une expression fluente en Trail.
39
+ *
40
+ * Syntaxe :
41
+ * entity → Frame(entity, UNRESOLVED)
42
+ * entity(id) → Frame(entity, id, RESOLVED)
43
+ * entity.other → Frame(entity) + Frame(other)
44
+ * entity(id).other(id2) → Frame(entity,id) + Frame(other,id2)
45
+ *
46
+ * Exemples :
47
+ * people → [people?]
48
+ * people(Nolan) → [people(Nolan)]
49
+ * people(Nolan).movies → [people(Nolan)] → [movies?]
50
+ * cinema.people(Nolan).movies(2) → [cinema] → [people(Nolan)] → [movies(2)]
51
+ *
52
+ * @param expr - Expression fluente
53
+ * @param init - Contextes global/user à injecter
54
+ */
55
+ static fromFluent(expr: string, init?: {
56
+ global?: Record<string, any>;
57
+ user?: Record<string, any>;
58
+ }): Trail;
59
+ /**
60
+ * Sérialise un Trail en path HTTP.
61
+ *
62
+ * Exemple :
63
+ * Trail([people(Nolan)][movies?]) → /people/Nolan/movies
64
+ */
65
+ static toPath(trail: Trail): string;
66
+ /**
67
+ * Sérialise un Trail en expression fluente.
68
+ *
69
+ * Exemple :
70
+ * Trail([people(Nolan)][movies?]) → people(Nolan).movies
71
+ */
72
+ static toFluent(trail: Trail): string;
73
+ /**
74
+ * Heuristique : un segment ressemble-t-il à un nom d'entité ?
75
+ * Les entités commencent par une lettre minuscule et ne contiennent
76
+ * que des lettres, chiffres et tirets.
77
+ */
78
+ private static looksLikeEntity;
79
+ /**
80
+ * Essaie de convertir un id en nombre, sinon garde la string.
81
+ */
82
+ private static coerceId;
83
+ /**
84
+ * Tokenise une expression fluente en segments.
85
+ * Préserve le contenu des parenthèses (les ids peuvent contenir des points).
86
+ *
87
+ * ex: "cinema.people(Nolan.Jr).movies"
88
+ * → ["cinema", "people(Nolan.Jr)", "movies"]
89
+ */
90
+ private static tokenizeFluent;
91
+ /**
92
+ * Parse un token "entity" ou "entity(id)" en Frame.
93
+ */
94
+ private static parseToken;
95
+ }
96
+ //# sourceMappingURL=TrailParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TrailParser.d.ts","sourceRoot":"","sources":["../../src/navigation/TrailParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGlC,qBAAa,WAAW;IAItB;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,QAAQ,CACb,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAO,GACtE,KAAK;IAyBR;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,UAAU,CACf,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAO,GACtE,KAAK;IAcR;;;;;OAKG;IACH,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAanC;;;;;OAKG;IACH,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAQrC;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAI9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ;IAKvB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAwB7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;CAqB1B"}