@gitwand/core 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +58 -0
  2. package/dist/__tests__/bench.bench.js +39 -0
  3. package/dist/__tests__/bench.bench.js.map +1 -1
  4. package/dist/__tests__/corpus.d.ts.map +1 -1
  5. package/dist/__tests__/corpus.js +363 -0
  6. package/dist/__tests__/corpus.js.map +1 -1
  7. package/dist/__tests__/diff/block-move.test.d.ts +5 -0
  8. package/dist/__tests__/diff/block-move.test.d.ts.map +1 -0
  9. package/dist/__tests__/diff/block-move.test.js +132 -0
  10. package/dist/__tests__/diff/block-move.test.js.map +1 -0
  11. package/dist/__tests__/diff/histogram.test.d.ts +8 -0
  12. package/dist/__tests__/diff/histogram.test.d.ts.map +1 -0
  13. package/dist/__tests__/diff/histogram.test.js +150 -0
  14. package/dist/__tests__/diff/histogram.test.js.map +1 -0
  15. package/dist/__tests__/diff/parity.test.d.ts +17 -0
  16. package/dist/__tests__/diff/parity.test.d.ts.map +1 -0
  17. package/dist/__tests__/diff/parity.test.js +149 -0
  18. package/dist/__tests__/diff/parity.test.js.map +1 -0
  19. package/dist/__tests__/diff.test.js +6 -2
  20. package/dist/__tests__/diff.test.js.map +1 -1
  21. package/dist/__tests__/format-profiles/integration.test.d.ts +7 -0
  22. package/dist/__tests__/format-profiles/integration.test.d.ts.map +1 -0
  23. package/dist/__tests__/format-profiles/integration.test.js +193 -0
  24. package/dist/__tests__/format-profiles/integration.test.js.map +1 -0
  25. package/dist/__tests__/format-profiles/json-patch.test.d.ts +12 -0
  26. package/dist/__tests__/format-profiles/json-patch.test.d.ts.map +1 -0
  27. package/dist/__tests__/format-profiles/json-patch.test.js +222 -0
  28. package/dist/__tests__/format-profiles/json-patch.test.js.map +1 -0
  29. package/dist/__tests__/format-profiles/registry.test.d.ts +5 -0
  30. package/dist/__tests__/format-profiles/registry.test.d.ts.map +1 -0
  31. package/dist/__tests__/format-profiles/registry.test.js +124 -0
  32. package/dist/__tests__/format-profiles/registry.test.js.map +1 -0
  33. package/dist/__tests__/patterns/make-score.test.d.ts +9 -0
  34. package/dist/__tests__/patterns/make-score.test.d.ts.map +1 -0
  35. package/dist/__tests__/patterns/make-score.test.js +49 -0
  36. package/dist/__tests__/patterns/make-score.test.js.map +1 -0
  37. package/dist/diff/block-move.d.ts +53 -0
  38. package/dist/diff/block-move.d.ts.map +1 -0
  39. package/dist/diff/block-move.js +192 -0
  40. package/dist/diff/block-move.js.map +1 -0
  41. package/dist/diff/histogram.d.ts +45 -0
  42. package/dist/diff/histogram.d.ts.map +1 -0
  43. package/dist/diff/histogram.js +172 -0
  44. package/dist/diff/histogram.js.map +1 -0
  45. package/dist/diff/index.d.ts +30 -0
  46. package/dist/diff/index.d.ts.map +1 -0
  47. package/dist/diff/index.js +47 -0
  48. package/dist/diff/index.js.map +1 -0
  49. package/dist/diff/lcs.d.ts +34 -0
  50. package/dist/diff/lcs.d.ts.map +1 -0
  51. package/dist/diff/lcs.js +184 -0
  52. package/dist/diff/lcs.js.map +1 -0
  53. package/dist/diff/shared.d.ts +54 -0
  54. package/dist/diff/shared.d.ts.map +1 -0
  55. package/dist/diff/shared.js +164 -0
  56. package/dist/diff/shared.js.map +1 -0
  57. package/dist/diff.d.ts +6 -65
  58. package/dist/diff.d.ts.map +1 -1
  59. package/dist/diff.js +6 -324
  60. package/dist/diff.js.map +1 -1
  61. package/dist/format-profiles/index.d.ts +34 -0
  62. package/dist/format-profiles/index.d.ts.map +1 -0
  63. package/dist/format-profiles/index.js +86 -0
  64. package/dist/format-profiles/index.js.map +1 -0
  65. package/dist/format-profiles/json-patch.d.ts +61 -0
  66. package/dist/format-profiles/json-patch.d.ts.map +1 -0
  67. package/dist/format-profiles/json-patch.js +269 -0
  68. package/dist/format-profiles/json-patch.js.map +1 -0
  69. package/dist/format-profiles/merge-strategies.d.ts +54 -0
  70. package/dist/format-profiles/merge-strategies.d.ts.map +1 -0
  71. package/dist/format-profiles/merge-strategies.js +156 -0
  72. package/dist/format-profiles/merge-strategies.js.map +1 -0
  73. package/dist/format-profiles/profiles/composer.d.ts +18 -0
  74. package/dist/format-profiles/profiles/composer.d.ts.map +1 -0
  75. package/dist/format-profiles/profiles/composer.js +45 -0
  76. package/dist/format-profiles/profiles/composer.js.map +1 -0
  77. package/dist/format-profiles/profiles/helm-values.d.ts +21 -0
  78. package/dist/format-profiles/profiles/helm-values.d.ts.map +1 -0
  79. package/dist/format-profiles/profiles/helm-values.js +40 -0
  80. package/dist/format-profiles/profiles/helm-values.js.map +1 -0
  81. package/dist/format-profiles/profiles/kubernetes.d.ts +22 -0
  82. package/dist/format-profiles/profiles/kubernetes.d.ts.map +1 -0
  83. package/dist/format-profiles/profiles/kubernetes.js +60 -0
  84. package/dist/format-profiles/profiles/kubernetes.js.map +1 -0
  85. package/dist/format-profiles/profiles/package-json.d.ts +18 -0
  86. package/dist/format-profiles/profiles/package-json.d.ts.map +1 -0
  87. package/dist/format-profiles/profiles/package-json.js +36 -0
  88. package/dist/format-profiles/profiles/package-json.js.map +1 -0
  89. package/dist/format-profiles/profiles/tsconfig.d.ts +21 -0
  90. package/dist/format-profiles/profiles/tsconfig.d.ts.map +1 -0
  91. package/dist/format-profiles/profiles/tsconfig.js +47 -0
  92. package/dist/format-profiles/profiles/tsconfig.js.map +1 -0
  93. package/dist/format-profiles/types.d.ts +67 -0
  94. package/dist/format-profiles/types.d.ts.map +1 -0
  95. package/dist/format-profiles/types.js +9 -0
  96. package/dist/format-profiles/types.js.map +1 -0
  97. package/dist/index.d.ts +4 -0
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +5 -0
  100. package/dist/index.js.map +1 -1
  101. package/dist/patterns/insertion-at-boundary.d.ts.map +1 -1
  102. package/dist/patterns/insertion-at-boundary.js +15 -33
  103. package/dist/patterns/insertion-at-boundary.js.map +1 -1
  104. package/dist/patterns/utils.d.ts +11 -8
  105. package/dist/patterns/utils.d.ts.map +1 -1
  106. package/dist/patterns/utils.js +28 -10
  107. package/dist/patterns/utils.js.map +1 -1
  108. package/dist/resolver/format-dispatch.d.ts.map +1 -1
  109. package/dist/resolver/format-dispatch.js +3 -1
  110. package/dist/resolver/format-dispatch.js.map +1 -1
  111. package/dist/resolver/policy.d.ts.map +1 -1
  112. package/dist/resolver/policy.js +2 -0
  113. package/dist/resolver/policy.js.map +1 -1
  114. package/dist/resolvers/dispatcher.d.ts +5 -1
  115. package/dist/resolvers/dispatcher.d.ts.map +1 -1
  116. package/dist/resolvers/dispatcher.js +8 -3
  117. package/dist/resolvers/dispatcher.js.map +1 -1
  118. package/dist/resolvers/json.d.ts +11 -2
  119. package/dist/resolvers/json.d.ts.map +1 -1
  120. package/dist/resolvers/json.js +55 -7
  121. package/dist/resolvers/json.js.map +1 -1
  122. package/dist/resolvers/yaml.d.ts +8 -2
  123. package/dist/resolvers/yaml.d.ts.map +1 -1
  124. package/dist/resolvers/yaml.js +156 -2
  125. package/dist/resolvers/yaml.js.map +1 -1
  126. package/dist/types.d.ts +25 -0
  127. package/dist/types.d.ts.map +1 -1
  128. package/package.json +1 -1
@@ -0,0 +1,34 @@
1
+ /**
2
+ * GitWand — Algorithme LCS (Longest Common Subsequence)
3
+ *
4
+ * Stratégie hybride DP plein (Int32Array) ↔ Hirschberg (mémoire O(min(n,m))),
5
+ * équivalente en sortie observable. C'est le **backend legacy** depuis v2.1 :
6
+ * la fonction publique `lcs()` réside dans `./index.ts` et route vers
7
+ * `histogramDiff` par défaut. `GITWAND_DIFF=lcs` rebascule sur ce module pour
8
+ * rollback ou comparaison.
9
+ */
10
+ /**
11
+ * Calcule la Longest Common Subsequence entre deux tableaux de lignes.
12
+ * Retourne les indices des lignes communes dans chaque tableau.
13
+ *
14
+ * Stratégie hybride :
15
+ * - petit/moyen (n*m ≤ 4M cellules) → DP plein O(n*m) avec `Int32Array`
16
+ * (4 octets/cellule vs 8-16 octets pour des `number[][]`) ;
17
+ * - gros → Hirschberg récursif, mémoire O(min(n,m)) + O(log n) de pile.
18
+ *
19
+ * Le comportement observable (tie-break, pairs retournées) est identique entre
20
+ * les deux branches — voir `src/__tests__/diff.test.ts`.
21
+ *
22
+ * **Note v2.1** : exporté sous le nom `lcsLegacy` pour disambiguer du wrapper
23
+ * public `lcs` (qui route vers Histogram par défaut). L'algo lui-même n'a pas
24
+ * changé.
25
+ */
26
+ export declare function lcsLegacy(a: string[], b: string[]): Array<[number, number]>;
27
+ /**
28
+ * Implémentation Hirschberg exposée pour les tests (et usage avancé éventuel).
29
+ * L'API publique `lcs()` choisit automatiquement entre cette variante et le DP
30
+ * plein selon la taille de l'input. Exporter sous le préfixe `_` signale son
31
+ * caractère d'interne-testable.
32
+ */
33
+ export declare const _lcsHirschberg: (a: string[], b: string[]) => Array<[number, number]>;
34
+ //# sourceMappingURL=lcs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lcs.d.ts","sourceRoot":"","sources":["../../src/diff/lcs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAS3E;AA+CD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,GAAG,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,KAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAC3D,CAAC"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * GitWand — Algorithme LCS (Longest Common Subsequence)
3
+ *
4
+ * Stratégie hybride DP plein (Int32Array) ↔ Hirschberg (mémoire O(min(n,m))),
5
+ * équivalente en sortie observable. C'est le **backend legacy** depuis v2.1 :
6
+ * la fonction publique `lcs()` réside dans `./index.ts` et route vers
7
+ * `histogramDiff` par défaut. `GITWAND_DIFF=lcs` rebascule sur ce module pour
8
+ * rollback ou comparaison.
9
+ */
10
+ /**
11
+ * Seuil au-delà duquel on bascule sur Hirschberg (mémoire O(min(n,m))) au lieu
12
+ * du DP plein (mémoire O(n*m)). À 4M cellules → ~16MB avec un Int32Array, déjà
13
+ * lourd en mémoire mais tolérable en pic. Au-dessus, Hirschberg est obligatoire
14
+ * pour éviter un OOM sur les gros fichiers (lockfiles, bundles minifiés…).
15
+ */
16
+ const HIRSCHBERG_THRESHOLD = 4_000_000;
17
+ /**
18
+ * Calcule la Longest Common Subsequence entre deux tableaux de lignes.
19
+ * Retourne les indices des lignes communes dans chaque tableau.
20
+ *
21
+ * Stratégie hybride :
22
+ * - petit/moyen (n*m ≤ 4M cellules) → DP plein O(n*m) avec `Int32Array`
23
+ * (4 octets/cellule vs 8-16 octets pour des `number[][]`) ;
24
+ * - gros → Hirschberg récursif, mémoire O(min(n,m)) + O(log n) de pile.
25
+ *
26
+ * Le comportement observable (tie-break, pairs retournées) est identique entre
27
+ * les deux branches — voir `src/__tests__/diff.test.ts`.
28
+ *
29
+ * **Note v2.1** : exporté sous le nom `lcsLegacy` pour disambiguer du wrapper
30
+ * public `lcs` (qui route vers Histogram par défaut). L'algo lui-même n'a pas
31
+ * changé.
32
+ */
33
+ export function lcsLegacy(a, b) {
34
+ const n = a.length;
35
+ const m = b.length;
36
+ if (n === 0 || m === 0)
37
+ return [];
38
+ if (n * m <= HIRSCHBERG_THRESHOLD) {
39
+ return lcsDenseDP(a, b);
40
+ }
41
+ return lcsHirschberg(a, b);
42
+ }
43
+ /**
44
+ * DP plein avec `Int32Array` (mémoire compacte, 4 octets/cellule).
45
+ * Équivalent structurel à l'implémentation historique — même tie-break,
46
+ * mêmes paires retournées.
47
+ */
48
+ function lcsDenseDP(a, b) {
49
+ const n = a.length;
50
+ const m = b.length;
51
+ const W = m + 1;
52
+ // Table DP aplatie : dp[i*W + j] ≡ dp[i][j].
53
+ const dp = new Int32Array((n + 1) * W);
54
+ for (let i = 1; i <= n; i++) {
55
+ const row = i * W;
56
+ const prev = (i - 1) * W;
57
+ for (let j = 1; j <= m; j++) {
58
+ if (a[i - 1] === b[j - 1]) {
59
+ dp[row + j] = dp[prev + (j - 1)] + 1;
60
+ }
61
+ else {
62
+ const up = dp[prev + j];
63
+ const left = dp[row + (j - 1)];
64
+ dp[row + j] = up > left ? up : left;
65
+ }
66
+ }
67
+ }
68
+ // Backtrack : mêmes règles de tie-break que l'implémentation historique.
69
+ const result = [];
70
+ let i = n;
71
+ let j = m;
72
+ while (i > 0 && j > 0) {
73
+ if (a[i - 1] === b[j - 1]) {
74
+ result.push([i - 1, j - 1]);
75
+ i--;
76
+ j--;
77
+ }
78
+ else if (dp[(i - 1) * W + j] > dp[i * W + (j - 1)]) {
79
+ i--;
80
+ }
81
+ else {
82
+ j--;
83
+ }
84
+ }
85
+ result.reverse();
86
+ return result;
87
+ }
88
+ /**
89
+ * Implémentation Hirschberg exposée pour les tests (et usage avancé éventuel).
90
+ * L'API publique `lcs()` choisit automatiquement entre cette variante et le DP
91
+ * plein selon la taille de l'input. Exporter sous le préfixe `_` signale son
92
+ * caractère d'interne-testable.
93
+ */
94
+ export const _lcsHirschberg = (a, b) => lcsHirschberg(a, b);
95
+ /**
96
+ * Hirschberg : divide-and-conquer qui trouve le point de split optimal dans `a`
97
+ * en utilisant seulement 2 lignes de DP (mémoire O(min(n,m))), puis recurse sur
98
+ * les deux moitiés. Les paires LCS retournées peuvent différer de celles du DP
99
+ * plein **sur les ties**, mais la longueur et la validité sont garanties.
100
+ *
101
+ * Stratégie pour rester iso-comportement avec `lcsDenseDP` :
102
+ * - Sous un petit seuil de récursion (`n ≤ 2` ou `m ≤ 2`), on tombe sur des
103
+ * cas triviaux résolus directement (même tie-break que le DP plein).
104
+ * - Le split choisit le `j*` qui maximise `scoreL[j] + scoreR[m - j]`, et en
105
+ * cas d'ex-æquo on prend le **plus petit** `j*` (équivalent au tie-break
106
+ * "j-- d'abord" du backtrack historique).
107
+ */
108
+ function lcsHirschberg(a, b) {
109
+ const n = a.length;
110
+ const m = b.length;
111
+ // Cas de base : une seule ligne à gauche → chercher la première occurrence.
112
+ if (n === 0 || m === 0)
113
+ return [];
114
+ if (n === 1) {
115
+ const target = a[0];
116
+ for (let j = 0; j < m; j++) {
117
+ if (b[j] === target)
118
+ return [[0, j]];
119
+ }
120
+ return [];
121
+ }
122
+ const mid = n >> 1; // n / 2 floor
123
+ // Scores DP pour a[0..mid] contre b (forward), longueur m+1.
124
+ const scoreL = lcsScoreRow(a, 0, mid, b, 0, m, false);
125
+ // Scores DP pour a[mid..n] contre b (reverse), longueur m+1.
126
+ const scoreR = lcsScoreRow(a, mid, n, b, 0, m, true);
127
+ // Trouver le j* qui maximise scoreL[j] + scoreR[m - j].
128
+ // En cas d'ex-æquo, on prend le plus petit j pour rester proche du tie-break
129
+ // historique (backtrack « j-- en premier » ≈ préférer les splits « early »).
130
+ let bestJ = 0;
131
+ let bestScore = scoreL[0] + scoreR[m];
132
+ for (let j = 1; j <= m; j++) {
133
+ const s = scoreL[j] + scoreR[m - j];
134
+ if (s > bestScore) {
135
+ bestScore = s;
136
+ bestJ = j;
137
+ }
138
+ }
139
+ // Récursion + ajustement des indices pour la moitié droite.
140
+ const left = lcsHirschberg(a.slice(0, mid), b.slice(0, bestJ));
141
+ const rightRaw = lcsHirschberg(a.slice(mid), b.slice(bestJ));
142
+ const right = rightRaw.map(([i, j]) => [i + mid, j + bestJ]);
143
+ return left.concat(right);
144
+ }
145
+ /**
146
+ * Calcule la dernière ligne du tableau DP LCS en 2 lignes (mémoire O(m+1)).
147
+ *
148
+ * @param a - tableau source pour la dimension « rows »
149
+ * @param aStart - début (inclus) dans a
150
+ * @param aEnd - fin (exclus) dans a
151
+ * @param b - tableau source pour la dimension « cols »
152
+ * @param bStart - début (inclus) dans b
153
+ * @param bEnd - fin (exclus) dans b
154
+ * @param reverse - si true, parcourt a et b à l'envers (pour Hirschberg)
155
+ */
156
+ function lcsScoreRow(a, aStart, aEnd, b, bStart, bEnd, reverse) {
157
+ const n = aEnd - aStart;
158
+ const m = bEnd - bStart;
159
+ let prev = new Int32Array(m + 1);
160
+ let curr = new Int32Array(m + 1);
161
+ for (let i = 1; i <= n; i++) {
162
+ const ai = reverse ? a[aEnd - i] : a[aStart + i - 1];
163
+ for (let j = 1; j <= m; j++) {
164
+ const bj = reverse ? b[bEnd - j] : b[bStart + j - 1];
165
+ if (ai === bj) {
166
+ curr[j] = prev[j - 1] + 1;
167
+ }
168
+ else {
169
+ const up = prev[j];
170
+ const left = curr[j - 1];
171
+ curr[j] = up > left ? up : left;
172
+ }
173
+ }
174
+ // Swap prev ↔ curr (éviter une réallocation)
175
+ const tmp = prev;
176
+ prev = curr;
177
+ curr = tmp;
178
+ // Reset curr à 0 pour la prochaine itération
179
+ curr.fill(0);
180
+ }
181
+ // Après la boucle, la dernière ligne calculée est dans `prev`.
182
+ return prev;
183
+ }
184
+ //# sourceMappingURL=lcs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lcs.js","sourceRoot":"","sources":["../../src/diff/lcs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * GitWand — Helpers partagés au-dessus du backend diff
3
+ *
4
+ * `computeDiff`, `extractEdits`, `editsOverlap`, `mergeNonOverlapping` n'appartiennent
5
+ * pas à un algorithme particulier — ce sont des opérations *sur* le résultat d'un
6
+ * LCS. On les isole de l'implémentation pour pouvoir échanger librement le backend
7
+ * (`lcsLegacy` ↔ `histogramDiff`) sans toucher cette couche.
8
+ */
9
+ /** Une opération de diff sur une ligne */
10
+ export interface DiffOp {
11
+ type: "keep" | "add" | "remove";
12
+ line: string;
13
+ /** Index dans le tableau source (base pour keep/remove, branch pour add) */
14
+ index: number;
15
+ }
16
+ /**
17
+ * Calcule le diff entre une base et une branche.
18
+ * Retourne la séquence d'opérations (keep, add, remove).
19
+ *
20
+ * Utilise le backend `lcs()` du module index (Histogram par défaut depuis v2.1,
21
+ * `lcsLegacy` si `GITWAND_DIFF=lcs`).
22
+ */
23
+ export declare function computeDiff(base: string[], branch: string[]): DiffOp[];
24
+ /**
25
+ * Représente un changement (edit) d'une branche par rapport à la base.
26
+ * start/end sont les indices dans la base où le changement s'applique.
27
+ */
28
+ export interface Edit {
29
+ /** Index de début dans la base (inclus) — position avant laquelle insérer ou début de la zone supprimée */
30
+ baseStart: number;
31
+ /** Index de fin dans la base (exclus) — fin de la zone supprimée */
32
+ baseEnd: number;
33
+ /** Lignes ajoutées à cette position */
34
+ addedLines: string[];
35
+ /** Source : "ours" ou "theirs" */
36
+ source: "ours" | "theirs";
37
+ }
38
+ /**
39
+ * Extrait les edits (changements groupés) d'un diff.
40
+ * Chaque groupe contigu de add/remove forme un edit.
41
+ */
42
+ export declare function extractEdits(diff: DiffOp[], source: "ours" | "theirs"): Edit[];
43
+ /**
44
+ * Vérifie si deux edits se chevauchent (overlap).
45
+ * Deux edits overlap si leurs zones dans la base se croisent.
46
+ */
47
+ export declare function editsOverlap(a: Edit, b: Edit): boolean;
48
+ /**
49
+ * Tente de fusionner les changements non-overlapping de deux branches.
50
+ *
51
+ * @returns Les lignes fusionnées, ou null si les changements se chevauchent
52
+ */
53
+ export declare function mergeNonOverlapping(base: string[], ours: string[], theirs: string[]): string[] | null;
54
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/diff/shared.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,0CAA0C;AAC1C,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAmCtE;AAED;;;GAGG;AACH,MAAM,WAAW,IAAI;IACnB,2GAA2G;IAC3G,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kCAAkC;IAClC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,MAAM,GAAG,QAAQ,GACxB,IAAI,EAAE,CAqCR;AAmBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,OAAO,CAmBtD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,EAAE,GAAG,IAAI,CAgDjB"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * GitWand — Helpers partagés au-dessus du backend diff
3
+ *
4
+ * `computeDiff`, `extractEdits`, `editsOverlap`, `mergeNonOverlapping` n'appartiennent
5
+ * pas à un algorithme particulier — ce sont des opérations *sur* le résultat d'un
6
+ * LCS. On les isole de l'implémentation pour pouvoir échanger librement le backend
7
+ * (`lcsLegacy` ↔ `histogramDiff`) sans toucher cette couche.
8
+ */
9
+ import { lcs } from "./index.js";
10
+ /**
11
+ * Calcule le diff entre une base et une branche.
12
+ * Retourne la séquence d'opérations (keep, add, remove).
13
+ *
14
+ * Utilise le backend `lcs()` du module index (Histogram par défaut depuis v2.1,
15
+ * `lcsLegacy` si `GITWAND_DIFF=lcs`).
16
+ */
17
+ export function computeDiff(base, branch) {
18
+ const common = lcs(base, branch);
19
+ const ops = [];
20
+ let baseIdx = 0;
21
+ let branchIdx = 0;
22
+ for (const [bIdx, rIdx] of common) {
23
+ // Lignes supprimées de la base (avant le prochain match)
24
+ while (baseIdx < bIdx) {
25
+ ops.push({ type: "remove", line: base[baseIdx], index: baseIdx });
26
+ baseIdx++;
27
+ }
28
+ // Lignes ajoutées dans la branche (avant le prochain match)
29
+ while (branchIdx < rIdx) {
30
+ ops.push({ type: "add", line: branch[branchIdx], index: branchIdx });
31
+ branchIdx++;
32
+ }
33
+ // Ligne commune
34
+ ops.push({ type: "keep", line: base[baseIdx], index: baseIdx });
35
+ baseIdx++;
36
+ branchIdx++;
37
+ }
38
+ // Lignes restantes après le dernier match
39
+ while (baseIdx < base.length) {
40
+ ops.push({ type: "remove", line: base[baseIdx], index: baseIdx });
41
+ baseIdx++;
42
+ }
43
+ while (branchIdx < branch.length) {
44
+ ops.push({ type: "add", line: branch[branchIdx], index: branchIdx });
45
+ branchIdx++;
46
+ }
47
+ return ops;
48
+ }
49
+ /**
50
+ * Extrait les edits (changements groupés) d'un diff.
51
+ * Chaque groupe contigu de add/remove forme un edit.
52
+ */
53
+ export function extractEdits(diff, source) {
54
+ const edits = [];
55
+ let i = 0;
56
+ while (i < diff.length) {
57
+ if (diff[i].type === "keep") {
58
+ i++;
59
+ continue;
60
+ }
61
+ // Début d'un groupe de changements
62
+ const removedLines = [];
63
+ const addedLines = [];
64
+ while (i < diff.length && diff[i].type !== "keep") {
65
+ if (diff[i].type === "remove") {
66
+ removedLines.push(diff[i].index);
67
+ }
68
+ else {
69
+ addedLines.push(diff[i].line);
70
+ }
71
+ i++;
72
+ }
73
+ const baseStart = removedLines.length > 0
74
+ ? removedLines[0]
75
+ : // Pour un pur ajout, on utilise l'index de la prochaine ligne keep
76
+ findNextKeepBaseIndex(diff, i);
77
+ const baseEnd = removedLines.length > 0
78
+ ? removedLines[removedLines.length - 1] + 1
79
+ : baseStart; // Pur ajout : pas de suppression
80
+ edits.push({ baseStart, baseEnd, addedLines, source });
81
+ }
82
+ return edits;
83
+ }
84
+ /** Trouve l'index base de la prochaine opération "keep" à partir de la position i */
85
+ function findNextKeepBaseIndex(diff, fromIdx) {
86
+ for (let j = fromIdx; j < diff.length; j++) {
87
+ if (diff[j].type === "keep") {
88
+ return diff[j].index;
89
+ }
90
+ }
91
+ // Si pas de keep après, c'est un ajout en fin de fichier
92
+ // On retourne l'index après la dernière ligne de la base
93
+ for (let j = diff.length - 1; j >= 0; j--) {
94
+ if (diff[j].type === "keep" || diff[j].type === "remove") {
95
+ return diff[j].index + 1;
96
+ }
97
+ }
98
+ return 0;
99
+ }
100
+ /**
101
+ * Vérifie si deux edits se chevauchent (overlap).
102
+ * Deux edits overlap si leurs zones dans la base se croisent.
103
+ */
104
+ export function editsOverlap(a, b) {
105
+ // Les edits sont des intervalles [baseStart, baseEnd) dans la base
106
+ // Ils overlap si un commence avant que l'autre finisse
107
+ // Cas spécial : deux purs ajouts au même point
108
+ if (a.baseStart === a.baseEnd && b.baseStart === b.baseEnd) {
109
+ return a.baseStart === b.baseStart;
110
+ }
111
+ // Cas spécial : un pur ajout à un point touché par l'autre
112
+ if (a.baseStart === a.baseEnd) {
113
+ return a.baseStart >= b.baseStart && a.baseStart < b.baseEnd;
114
+ }
115
+ if (b.baseStart === b.baseEnd) {
116
+ return b.baseStart >= a.baseStart && b.baseStart < a.baseEnd;
117
+ }
118
+ // Cas général : overlap d'intervalles
119
+ return a.baseStart < b.baseEnd && b.baseStart < a.baseEnd;
120
+ }
121
+ /**
122
+ * Tente de fusionner les changements non-overlapping de deux branches.
123
+ *
124
+ * @returns Les lignes fusionnées, ou null si les changements se chevauchent
125
+ */
126
+ export function mergeNonOverlapping(base, ours, theirs) {
127
+ const oursDiff = computeDiff(base, ours);
128
+ const theirsDiff = computeDiff(base, theirs);
129
+ const oursEdits = extractEdits(oursDiff, "ours");
130
+ const theirsEdits = extractEdits(theirsDiff, "theirs");
131
+ // Vérifier qu'aucun edit ne chevauche un edit de l'autre branche
132
+ for (const oEdit of oursEdits) {
133
+ for (const tEdit of theirsEdits) {
134
+ if (editsOverlap(oEdit, tEdit)) {
135
+ return null; // Overlap détecté → pas de résolution automatique
136
+ }
137
+ }
138
+ }
139
+ // Fusionner les edits triés par position dans la base
140
+ const allEdits = [...oursEdits, ...theirsEdits].sort((a, b) => a.baseStart - b.baseStart || a.baseEnd - b.baseEnd);
141
+ // Reconstruire le fichier fusionné
142
+ const result = [];
143
+ let baseIdx = 0;
144
+ for (const edit of allEdits) {
145
+ // Copier les lignes de la base jusqu'au début de l'edit
146
+ while (baseIdx < edit.baseStart) {
147
+ result.push(base[baseIdx]);
148
+ baseIdx++;
149
+ }
150
+ // Ajouter les lignes de l'edit
151
+ result.push(...edit.addedLines);
152
+ // Avancer au-delà de la zone supprimée
153
+ if (edit.baseEnd > baseIdx) {
154
+ baseIdx = edit.baseEnd;
155
+ }
156
+ }
157
+ // Copier le reste de la base
158
+ while (baseIdx < base.length) {
159
+ result.push(base[baseIdx]);
160
+ baseIdx++;
161
+ }
162
+ return result;
163
+ }
164
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/diff/shared.ts"],"names":[],"mappings":"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"}
package/dist/diff.d.ts CHANGED
@@ -1,69 +1,10 @@
1
1
  /**
2
- * GitWand Diff Utilities
2
+ * GitWand Shim de rétro-compat pour `src/diff.ts`
3
3
  *
4
- * Algorithme LCS (Longest Common Subsequence) et 3-way merge
5
- * pour détecter et fusionner les changements non-overlapping.
4
+ * Depuis v2.1 le moteur diff vit dans `src/diff/`. Ce fichier re-exporte tout
5
+ * pour que les imports `from "../diff.js"` continuent de marcher sans churn
6
+ * dans les patterns et résolveurs. Sera supprimé en v2.2 — d'ici là, ne pas
7
+ * ajouter de nouvelle logique ici.
6
8
  */
7
- /** Une opération de diff sur une ligne */
8
- export interface DiffOp {
9
- type: "keep" | "add" | "remove";
10
- line: string;
11
- /** Index dans le tableau source (base pour keep/remove, branch pour add) */
12
- index: number;
13
- }
14
- /**
15
- * Calcule la Longest Common Subsequence entre deux tableaux de lignes.
16
- * Retourne les indices des lignes communes dans chaque tableau.
17
- *
18
- * Stratégie hybride (P2.1) :
19
- * - petit/moyen (n*m ≤ 4M cellules) → DP plein O(n*m) avec `Int32Array`
20
- * (4 octets/cellule vs 8-16 octets pour des `number[][]`) ;
21
- * - gros → Hirschberg récursif, mémoire O(min(n,m)) + O(log n) de pile.
22
- *
23
- * Le comportement observable (tie-break, pairs retournées) est identique entre
24
- * les deux branches — voir `src/__tests__/diff.test.ts`.
25
- */
26
- export declare function lcs(a: string[], b: string[]): Array<[number, number]>;
27
- /**
28
- * Implémentation Hirschberg exposée pour les tests (et usage avancé éventuel).
29
- * L'API publique `lcs()` choisit automatiquement entre cette variante et le DP
30
- * plein selon la taille de l'input. Exporter sous le préfixe `_` signale son
31
- * caractère d'interne-testable.
32
- */
33
- export declare const _lcsHirschberg: (a: string[], b: string[]) => Array<[number, number]>;
34
- /**
35
- * Calcule le diff entre une base et une branche.
36
- * Retourne la séquence d'opérations (keep, add, remove).
37
- */
38
- export declare function computeDiff(base: string[], branch: string[]): DiffOp[];
39
- /**
40
- * Représente un changement (edit) d'une branche par rapport à la base.
41
- * start/end sont les indices dans la base où le changement s'applique.
42
- */
43
- export interface Edit {
44
- /** Index de début dans la base (inclus) — position avant laquelle insérer ou début de la zone supprimée */
45
- baseStart: number;
46
- /** Index de fin dans la base (exclus) — fin de la zone supprimée */
47
- baseEnd: number;
48
- /** Lignes ajoutées à cette position */
49
- addedLines: string[];
50
- /** Source : "ours" ou "theirs" */
51
- source: "ours" | "theirs";
52
- }
53
- /**
54
- * Extrait les edits (changements groupés) d'un diff.
55
- * Chaque groupe contigu de add/remove forme un edit.
56
- */
57
- export declare function extractEdits(diff: DiffOp[], source: "ours" | "theirs"): Edit[];
58
- /**
59
- * Vérifie si deux edits se chevauchent (overlap).
60
- * Deux edits overlap si leurs zones dans la base se croisent.
61
- */
62
- export declare function editsOverlap(a: Edit, b: Edit): boolean;
63
- /**
64
- * Tente de fusionner les changements non-overlapping de deux branches.
65
- *
66
- * @returns Les lignes fusionnées, ou null si les changements se chevauchent
67
- */
68
- export declare function mergeNonOverlapping(base: string[], ours: string[], theirs: string[]): string[] | null;
9
+ export * from "./diff/index.js";
69
10
  //# sourceMappingURL=diff.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,0CAA0C;AAC1C,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;CACf;AAUD;;;;;;;;;;;GAWG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CASrE;AA+CD;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GAAI,GAAG,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,KAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAC3D,CAAC;AAuGtB;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAmCtE;AAED;;;GAGG;AACH,MAAM,WAAW,IAAI;IACnB,2GAA2G;IAC3G,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kCAAkC;IAClC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,MAAM,GAAG,QAAQ,GACxB,IAAI,EAAE,CAqCR;AAmBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,OAAO,CAmBtD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,EAAE,GAAG,IAAI,CAgDjB"}
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,iBAAiB,CAAC"}