@gitwand/core 2.0.1 → 2.3.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 (200) 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/__tests__/structural/grandeur-nature.test.d.ts +31 -0
  38. package/dist/__tests__/structural/grandeur-nature.test.d.ts.map +1 -0
  39. package/dist/__tests__/structural/grandeur-nature.test.js +264 -0
  40. package/dist/__tests__/structural/grandeur-nature.test.js.map +1 -0
  41. package/dist/__tests__/structural/languages.test.d.ts +5 -0
  42. package/dist/__tests__/structural/languages.test.d.ts.map +1 -0
  43. package/dist/__tests__/structural/languages.test.js +74 -0
  44. package/dist/__tests__/structural/languages.test.js.map +1 -0
  45. package/dist/__tests__/structural/matching.test.d.ts +6 -0
  46. package/dist/__tests__/structural/matching.test.d.ts.map +1 -0
  47. package/dist/__tests__/structural/matching.test.js +113 -0
  48. package/dist/__tests__/structural/matching.test.js.map +1 -0
  49. package/dist/__tests__/structural/merge.test.d.ts +6 -0
  50. package/dist/__tests__/structural/merge.test.d.ts.map +1 -0
  51. package/dist/__tests__/structural/merge.test.js +117 -0
  52. package/dist/__tests__/structural/merge.test.js.map +1 -0
  53. package/dist/__tests__/structural/reconstruct.test.d.ts +6 -0
  54. package/dist/__tests__/structural/reconstruct.test.d.ts.map +1 -0
  55. package/dist/__tests__/structural/reconstruct.test.js +104 -0
  56. package/dist/__tests__/structural/reconstruct.test.js.map +1 -0
  57. package/dist/__tests__/structural/structural-index.test.d.ts +14 -0
  58. package/dist/__tests__/structural/structural-index.test.d.ts.map +1 -0
  59. package/dist/__tests__/structural/structural-index.test.js +108 -0
  60. package/dist/__tests__/structural/structural-index.test.js.map +1 -0
  61. package/dist/diff/block-move.d.ts +53 -0
  62. package/dist/diff/block-move.d.ts.map +1 -0
  63. package/dist/diff/block-move.js +192 -0
  64. package/dist/diff/block-move.js.map +1 -0
  65. package/dist/diff/histogram.d.ts +45 -0
  66. package/dist/diff/histogram.d.ts.map +1 -0
  67. package/dist/diff/histogram.js +172 -0
  68. package/dist/diff/histogram.js.map +1 -0
  69. package/dist/diff/index.d.ts +30 -0
  70. package/dist/diff/index.d.ts.map +1 -0
  71. package/dist/diff/index.js +47 -0
  72. package/dist/diff/index.js.map +1 -0
  73. package/dist/diff/lcs.d.ts +34 -0
  74. package/dist/diff/lcs.d.ts.map +1 -0
  75. package/dist/diff/lcs.js +184 -0
  76. package/dist/diff/lcs.js.map +1 -0
  77. package/dist/diff/shared.d.ts +54 -0
  78. package/dist/diff/shared.d.ts.map +1 -0
  79. package/dist/diff/shared.js +164 -0
  80. package/dist/diff/shared.js.map +1 -0
  81. package/dist/diff.d.ts +6 -65
  82. package/dist/diff.d.ts.map +1 -1
  83. package/dist/diff.js +6 -324
  84. package/dist/diff.js.map +1 -1
  85. package/dist/format-profiles/index.d.ts +34 -0
  86. package/dist/format-profiles/index.d.ts.map +1 -0
  87. package/dist/format-profiles/index.js +86 -0
  88. package/dist/format-profiles/index.js.map +1 -0
  89. package/dist/format-profiles/json-patch.d.ts +61 -0
  90. package/dist/format-profiles/json-patch.d.ts.map +1 -0
  91. package/dist/format-profiles/json-patch.js +269 -0
  92. package/dist/format-profiles/json-patch.js.map +1 -0
  93. package/dist/format-profiles/merge-strategies.d.ts +54 -0
  94. package/dist/format-profiles/merge-strategies.d.ts.map +1 -0
  95. package/dist/format-profiles/merge-strategies.js +156 -0
  96. package/dist/format-profiles/merge-strategies.js.map +1 -0
  97. package/dist/format-profiles/profiles/composer.d.ts +18 -0
  98. package/dist/format-profiles/profiles/composer.d.ts.map +1 -0
  99. package/dist/format-profiles/profiles/composer.js +45 -0
  100. package/dist/format-profiles/profiles/composer.js.map +1 -0
  101. package/dist/format-profiles/profiles/helm-values.d.ts +21 -0
  102. package/dist/format-profiles/profiles/helm-values.d.ts.map +1 -0
  103. package/dist/format-profiles/profiles/helm-values.js +40 -0
  104. package/dist/format-profiles/profiles/helm-values.js.map +1 -0
  105. package/dist/format-profiles/profiles/kubernetes.d.ts +22 -0
  106. package/dist/format-profiles/profiles/kubernetes.d.ts.map +1 -0
  107. package/dist/format-profiles/profiles/kubernetes.js +60 -0
  108. package/dist/format-profiles/profiles/kubernetes.js.map +1 -0
  109. package/dist/format-profiles/profiles/package-json.d.ts +18 -0
  110. package/dist/format-profiles/profiles/package-json.d.ts.map +1 -0
  111. package/dist/format-profiles/profiles/package-json.js +36 -0
  112. package/dist/format-profiles/profiles/package-json.js.map +1 -0
  113. package/dist/format-profiles/profiles/tsconfig.d.ts +21 -0
  114. package/dist/format-profiles/profiles/tsconfig.d.ts.map +1 -0
  115. package/dist/format-profiles/profiles/tsconfig.js +47 -0
  116. package/dist/format-profiles/profiles/tsconfig.js.map +1 -0
  117. package/dist/format-profiles/types.d.ts +67 -0
  118. package/dist/format-profiles/types.d.ts.map +1 -0
  119. package/dist/format-profiles/types.js +9 -0
  120. package/dist/format-profiles/types.js.map +1 -0
  121. package/dist/index.d.ts +9 -1
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +10 -1
  124. package/dist/index.js.map +1 -1
  125. package/dist/patterns/insertion-at-boundary.d.ts.map +1 -1
  126. package/dist/patterns/insertion-at-boundary.js +15 -33
  127. package/dist/patterns/insertion-at-boundary.js.map +1 -1
  128. package/dist/patterns/utils.d.ts +11 -8
  129. package/dist/patterns/utils.d.ts.map +1 -1
  130. package/dist/patterns/utils.js +28 -10
  131. package/dist/patterns/utils.js.map +1 -1
  132. package/dist/resolver/format-dispatch.d.ts.map +1 -1
  133. package/dist/resolver/format-dispatch.js +3 -1
  134. package/dist/resolver/format-dispatch.js.map +1 -1
  135. package/dist/resolver/index.d.ts +14 -0
  136. package/dist/resolver/index.d.ts.map +1 -1
  137. package/dist/resolver/index.js +29 -0
  138. package/dist/resolver/index.js.map +1 -1
  139. package/dist/resolver/policy.d.ts.map +1 -1
  140. package/dist/resolver/policy.js +2 -0
  141. package/dist/resolver/policy.js.map +1 -1
  142. package/dist/resolvers/dispatcher.d.ts +22 -2
  143. package/dist/resolvers/dispatcher.d.ts.map +1 -1
  144. package/dist/resolvers/dispatcher.js +8 -3
  145. package/dist/resolvers/dispatcher.js.map +1 -1
  146. package/dist/resolvers/json.d.ts +11 -2
  147. package/dist/resolvers/json.d.ts.map +1 -1
  148. package/dist/resolvers/json.js +55 -7
  149. package/dist/resolvers/json.js.map +1 -1
  150. package/dist/resolvers/yaml.d.ts +8 -2
  151. package/dist/resolvers/yaml.d.ts.map +1 -1
  152. package/dist/resolvers/yaml.js +156 -2
  153. package/dist/resolvers/yaml.js.map +1 -1
  154. package/dist/structural/entities.d.ts +44 -0
  155. package/dist/structural/entities.d.ts.map +1 -0
  156. package/dist/structural/entities.js +315 -0
  157. package/dist/structural/entities.js.map +1 -0
  158. package/dist/structural/index.d.ts +48 -0
  159. package/dist/structural/index.d.ts.map +1 -0
  160. package/dist/structural/index.js +177 -0
  161. package/dist/structural/index.js.map +1 -0
  162. package/dist/structural/matching.d.ts +46 -0
  163. package/dist/structural/matching.d.ts.map +1 -0
  164. package/dist/structural/matching.js +83 -0
  165. package/dist/structural/matching.js.map +1 -0
  166. package/dist/structural/merge.d.ts +45 -0
  167. package/dist/structural/merge.d.ts.map +1 -0
  168. package/dist/structural/merge.js +127 -0
  169. package/dist/structural/merge.js.map +1 -0
  170. package/dist/structural/parsers/adapters/browser.d.ts +22 -0
  171. package/dist/structural/parsers/adapters/browser.d.ts.map +1 -0
  172. package/dist/structural/parsers/adapters/browser.js +27 -0
  173. package/dist/structural/parsers/adapters/browser.js.map +1 -0
  174. package/dist/structural/parsers/adapters/node.d.ts +18 -0
  175. package/dist/structural/parsers/adapters/node.d.ts.map +1 -0
  176. package/dist/structural/parsers/adapters/node.js +42 -0
  177. package/dist/structural/parsers/adapters/node.js.map +1 -0
  178. package/dist/structural/parsers/adapters/tauri.d.ts +26 -0
  179. package/dist/structural/parsers/adapters/tauri.d.ts.map +1 -0
  180. package/dist/structural/parsers/adapters/tauri.js +34 -0
  181. package/dist/structural/parsers/adapters/tauri.js.map +1 -0
  182. package/dist/structural/parsers/grammars/languages.d.ts +32 -0
  183. package/dist/structural/parsers/grammars/languages.d.ts.map +1 -0
  184. package/dist/structural/parsers/grammars/languages.js +73 -0
  185. package/dist/structural/parsers/grammars/languages.js.map +1 -0
  186. package/dist/structural/parsers/grammars/ts.d.ts +26 -0
  187. package/dist/structural/parsers/grammars/ts.d.ts.map +1 -0
  188. package/dist/structural/parsers/grammars/ts.js +46 -0
  189. package/dist/structural/parsers/grammars/ts.js.map +1 -0
  190. package/dist/structural/parsers/loader.d.ts +74 -0
  191. package/dist/structural/parsers/loader.d.ts.map +1 -0
  192. package/dist/structural/parsers/loader.js +181 -0
  193. package/dist/structural/parsers/loader.js.map +1 -0
  194. package/dist/structural/reconstruct.d.ts +28 -0
  195. package/dist/structural/reconstruct.d.ts.map +1 -0
  196. package/dist/structural/reconstruct.js +63 -0
  197. package/dist/structural/reconstruct.js.map +1 -0
  198. package/dist/types.d.ts +25 -0
  199. package/dist/types.d.ts.map +1 -1
  200. package/package.json +16 -2
@@ -0,0 +1,83 @@
1
+ /**
2
+ * 3-way entity matching for structural merge.
3
+ *
4
+ * Matches top-level entities across the three file versions (base / ours /
5
+ * theirs) using their `signature` as a stable key. Each entity triple is
6
+ * assigned a status that describes what happened to it during the merge.
7
+ */
8
+ // ─── Internal ─────────────────────────────────────────────────────────────────
9
+ function classifyMatch(base, ours, theirs) {
10
+ const inBase = base !== null;
11
+ const inOurs = ours !== null;
12
+ const inTheirs = theirs !== null;
13
+ // Not in base → newly added in this merge
14
+ if (!inBase) {
15
+ if (inOurs && inTheirs) {
16
+ return ours.text === theirs.text ? "both-changed-same" : "both-changed-diff";
17
+ }
18
+ if (inOurs)
19
+ return "ours-added";
20
+ if (inTheirs)
21
+ return "theirs-added";
22
+ // Unreachable: signature would not be in allSigs without being in at least one version
23
+ return "unchanged";
24
+ }
25
+ // Entity present in base — did ours/theirs change or delete it?
26
+ const inBothMissing = !inOurs && !inTheirs;
27
+ if (inBothMissing)
28
+ return "both-changed-same"; // both deleted = same outcome
29
+ if (!inOurs)
30
+ return "ours-deleted";
31
+ if (!inTheirs)
32
+ return "theirs-deleted";
33
+ const oursChanged = ours.text !== base.text;
34
+ const theirsChanged = theirs.text !== base.text;
35
+ if (!oursChanged && !theirsChanged)
36
+ return "unchanged";
37
+ if (oursChanged && !theirsChanged)
38
+ return "ours-only-change";
39
+ if (!oursChanged && theirsChanged)
40
+ return "theirs-only-change";
41
+ // Both changed
42
+ return ours.text === theirs.text ? "both-changed-same" : "both-changed-diff";
43
+ }
44
+ // ─── Public API ───────────────────────────────────────────────────────────────
45
+ /**
46
+ * Compute 3-way entity matches between base, ours, and theirs.
47
+ *
48
+ * The returned array covers every unique signature found across all three
49
+ * versions. Order follows: base order → ours-only → theirs-only sigs.
50
+ *
51
+ * @param base - Entities extracted from the base (ancestor) version
52
+ * @param ours - Entities extracted from our version (current branch)
53
+ * @param theirs - Entities extracted from their version (incoming branch)
54
+ */
55
+ export function matchEntities(base, ours, theirs) {
56
+ const baseMap = new Map(base.map((e) => [e.signature, e]));
57
+ const oursMap = new Map(ours.map((e) => [e.signature, e]));
58
+ const theirsMap = new Map(theirs.map((e) => [e.signature, e]));
59
+ // Collect all signatures, preserving a sensible order (base → ours-only → theirs-only)
60
+ const seen = new Set();
61
+ const orderedSigs = [];
62
+ for (const map of [baseMap, oursMap, theirsMap]) {
63
+ for (const sig of map.keys()) {
64
+ if (!seen.has(sig)) {
65
+ seen.add(sig);
66
+ orderedSigs.push(sig);
67
+ }
68
+ }
69
+ }
70
+ return orderedSigs.map((sig) => {
71
+ const b = baseMap.get(sig) ?? null;
72
+ const o = oursMap.get(sig) ?? null;
73
+ const t = theirsMap.get(sig) ?? null;
74
+ return {
75
+ signature: sig,
76
+ status: classifyMatch(b, o, t),
77
+ base: b,
78
+ ours: o,
79
+ theirs: t,
80
+ };
81
+ });
82
+ }
83
+ //# sourceMappingURL=matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matching.js","sourceRoot":"","sources":["../../src/structural/matching.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAkCH,iFAAiF;AAEjF,SAAS,aAAa,CACpB,IAA2B,EAC3B,IAA2B,EAC3B,MAA6B;IAE7B,MAAM,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7B,MAAM,QAAQ,GAAG,MAAM,KAAK,IAAI,CAAC;IAEjC,0CAA0C;IAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;YACvB,OAAO,IAAK,CAAC,IAAI,KAAK,MAAO,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAC;QACjF,CAAC;QACD,IAAI,MAAM;YAAE,OAAO,YAAY,CAAC;QAChC,IAAI,QAAQ;YAAE,OAAO,cAAc,CAAC;QACpC,uFAAuF;QACvF,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,gEAAgE;IAChE,MAAM,aAAa,GAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC;IAC3C,IAAI,aAAa;QAAE,OAAO,mBAAmB,CAAC,CAAC,8BAA8B;IAE7E,IAAI,CAAC,MAAM;QAAE,OAAO,cAAc,CAAC;IACnC,IAAI,CAAC,QAAQ;QAAE,OAAO,gBAAgB,CAAC;IAEvC,MAAM,WAAW,GAAG,IAAK,CAAC,IAAI,KAAK,IAAK,CAAC,IAAI,CAAC;IAC9C,MAAM,aAAa,GAAG,MAAO,CAAC,IAAI,KAAK,IAAK,CAAC,IAAI,CAAC;IAElD,IAAI,CAAC,WAAW,IAAI,CAAC,aAAa;QAAE,OAAO,WAAW,CAAC;IACvD,IAAI,WAAW,IAAI,CAAC,aAAa;QAAE,OAAO,kBAAkB,CAAC;IAC7D,IAAI,CAAC,WAAW,IAAI,aAAa;QAAE,OAAO,oBAAoB,CAAC;IAE/D,eAAe;IACf,OAAO,IAAK,CAAC,IAAI,KAAK,MAAO,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAC;AACjF,CAAC;AAED,iFAAiF;AAEjF;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAsB,EACtB,IAAsB,EACtB,MAAwB;IAExB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/D,uFAAuF;IACvF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;QAChD,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACd,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACnC,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACnC,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACrC,OAAO;YACL,SAAS,EAAE,GAAG;YACd,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9B,IAAI,EAAE,CAAC;YACP,IAAI,EAAE,CAAC;YACP,MAAM,EAAE,CAAC;SACV,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Entity-level merge decisions for structural merge.
3
+ *
4
+ * Given a 3-way entity match, decides which text version to use in the
5
+ * merged output. Conservative by design: if both sides changed an entity
6
+ * differently, we return a "conflict" result and abort the structural merge
7
+ * for the whole file (falling back to the hunk-based resolver).
8
+ */
9
+ import type { EntityMatch } from "./matching.js";
10
+ export interface EntityMergeResult {
11
+ signature: string;
12
+ /**
13
+ * Whether this entity should appear in the merged output.
14
+ * `false` means the entity was deleted by ours, theirs, or both.
15
+ */
16
+ include: boolean;
17
+ /**
18
+ * The text to emit for this entity in the merged file.
19
+ * `null` signals an unresolvable conflict (structural merge aborted).
20
+ */
21
+ mergedText: string | null;
22
+ /** Human-readable explanation of the merge decision */
23
+ reason: string;
24
+ }
25
+ /**
26
+ * Decide how to merge a single entity based on its 3-way match status.
27
+ *
28
+ * Rules (conservative, correct-by-default):
29
+ * - unchanged → emit as-is
30
+ * - both-changed-same → emit the common changed version
31
+ * - ours-only-change → emit ours
32
+ * - theirs-only-change → emit theirs
33
+ * - ours-added → emit ours (append after theirs structure)
34
+ * - theirs-added → emit theirs
35
+ * - ours-deleted → omit (unless theirs also modified it → conflict)
36
+ * - theirs-deleted → omit (unless ours also modified it → conflict)
37
+ * - both-changed-diff → conflict (return mergedText: null → abort)
38
+ */
39
+ export declare function mergeEntity(match: EntityMatch): EntityMergeResult;
40
+ /**
41
+ * Returns `true` if any entity merge has an unresolvable conflict
42
+ * (i.e. the structural merge cannot produce a clean output).
43
+ */
44
+ export declare function hasEntityConflict(merges: EntityMergeResult[]): boolean;
45
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/structural/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIjD,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,iBAAiB,CAwGjE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAEtE"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Entity-level merge decisions for structural merge.
3
+ *
4
+ * Given a 3-way entity match, decides which text version to use in the
5
+ * merged output. Conservative by design: if both sides changed an entity
6
+ * differently, we return a "conflict" result and abort the structural merge
7
+ * for the whole file (falling back to the hunk-based resolver).
8
+ */
9
+ // ─── Public API ───────────────────────────────────────────────────────────────
10
+ /**
11
+ * Decide how to merge a single entity based on its 3-way match status.
12
+ *
13
+ * Rules (conservative, correct-by-default):
14
+ * - unchanged → emit as-is
15
+ * - both-changed-same → emit the common changed version
16
+ * - ours-only-change → emit ours
17
+ * - theirs-only-change → emit theirs
18
+ * - ours-added → emit ours (append after theirs structure)
19
+ * - theirs-added → emit theirs
20
+ * - ours-deleted → omit (unless theirs also modified it → conflict)
21
+ * - theirs-deleted → omit (unless ours also modified it → conflict)
22
+ * - both-changed-diff → conflict (return mergedText: null → abort)
23
+ */
24
+ export function mergeEntity(match) {
25
+ const { signature, status, base, ours, theirs } = match;
26
+ switch (status) {
27
+ case "unchanged":
28
+ return {
29
+ signature,
30
+ include: true,
31
+ mergedText: (ours ?? theirs ?? base).text,
32
+ reason: "unchanged",
33
+ };
34
+ case "both-changed-same":
35
+ if (ours && theirs) {
36
+ return {
37
+ signature,
38
+ include: true,
39
+ mergedText: theirs.text,
40
+ reason: "both changed identically — taking theirs",
41
+ };
42
+ }
43
+ // Both deleted
44
+ return {
45
+ signature,
46
+ include: false,
47
+ mergedText: null,
48
+ reason: "both deleted",
49
+ };
50
+ case "ours-only-change":
51
+ return {
52
+ signature,
53
+ include: ours !== null,
54
+ mergedText: ours?.text ?? null,
55
+ reason: "ours-only change",
56
+ };
57
+ case "theirs-only-change":
58
+ return {
59
+ signature,
60
+ include: theirs !== null,
61
+ mergedText: theirs?.text ?? null,
62
+ reason: "theirs-only change",
63
+ };
64
+ case "ours-added":
65
+ return {
66
+ signature,
67
+ include: true,
68
+ mergedText: ours.text,
69
+ reason: "ours added",
70
+ };
71
+ case "theirs-added":
72
+ return {
73
+ signature,
74
+ include: true,
75
+ mergedText: theirs.text,
76
+ reason: "theirs added",
77
+ };
78
+ case "ours-deleted":
79
+ // If theirs also modified this entity, it's a conflict (we'd silently
80
+ // drop a change by theirs). Treat as unresolvable.
81
+ if (theirs && base && theirs.text !== base.text) {
82
+ return {
83
+ signature,
84
+ include: false,
85
+ mergedText: null,
86
+ reason: "conflict: ours deleted, theirs modified",
87
+ };
88
+ }
89
+ return {
90
+ signature,
91
+ include: false,
92
+ mergedText: null,
93
+ reason: "ours deleted",
94
+ };
95
+ case "theirs-deleted":
96
+ // Symmetric: if ours modified the entity, conflict.
97
+ if (ours && base && ours.text !== base.text) {
98
+ return {
99
+ signature,
100
+ include: false,
101
+ mergedText: null,
102
+ reason: "conflict: theirs deleted, ours modified",
103
+ };
104
+ }
105
+ return {
106
+ signature,
107
+ include: false,
108
+ mergedText: null,
109
+ reason: "theirs deleted",
110
+ };
111
+ case "both-changed-diff":
112
+ return {
113
+ signature,
114
+ include: false,
115
+ mergedText: null,
116
+ reason: "conflict: both changed differently",
117
+ };
118
+ }
119
+ }
120
+ /**
121
+ * Returns `true` if any entity merge has an unresolvable conflict
122
+ * (i.e. the structural merge cannot produce a clean output).
123
+ */
124
+ export function hasEntityConflict(merges) {
125
+ return merges.some((m) => m.include === false && m.reason.startsWith("conflict:"));
126
+ }
127
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/structural/merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Browser adapter for loading tree-sitter grammar WASM files.
3
+ *
4
+ * Fetches the WASM file from a URL. The bundler / dev server must make the
5
+ * grammar WASM files available at a known public URL.
6
+ *
7
+ * Configure via `LoaderOptions.grammarBaseUrl` (default: "/assets/grammars").
8
+ */
9
+ export interface BrowserLoaderOptions {
10
+ /** Base URL where grammar WASM files are served (no trailing slash). */
11
+ grammarBaseUrl?: string;
12
+ }
13
+ /**
14
+ * Load grammar WASM bytes via fetch.
15
+ *
16
+ * Fetches `{grammarBaseUrl}/{grammarName}.wasm`.
17
+ *
18
+ * @param grammarName - e.g. "tree-sitter-typescript"
19
+ * @param opts - Browser-specific options
20
+ */
21
+ export declare function loadGrammarBytes(grammarName: string, opts?: BrowserLoaderOptions): Promise<Uint8Array>;
22
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../../src/structural/parsers/adapters/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,oBAAyB,GAC9B,OAAO,CAAC,UAAU,CAAC,CAarB"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Browser adapter for loading tree-sitter grammar WASM files.
3
+ *
4
+ * Fetches the WASM file from a URL. The bundler / dev server must make the
5
+ * grammar WASM files available at a known public URL.
6
+ *
7
+ * Configure via `LoaderOptions.grammarBaseUrl` (default: "/assets/grammars").
8
+ */
9
+ /**
10
+ * Load grammar WASM bytes via fetch.
11
+ *
12
+ * Fetches `{grammarBaseUrl}/{grammarName}.wasm`.
13
+ *
14
+ * @param grammarName - e.g. "tree-sitter-typescript"
15
+ * @param opts - Browser-specific options
16
+ */
17
+ export async function loadGrammarBytes(grammarName, opts = {}) {
18
+ const base = opts.grammarBaseUrl ?? "/assets/grammars";
19
+ const url = `${base}/${grammarName}.wasm`;
20
+ const response = await fetch(url);
21
+ if (!response.ok) {
22
+ throw new Error(`[structural] Failed to fetch grammar WASM: ${url} (HTTP ${response.status})`);
23
+ }
24
+ const buffer = await response.arrayBuffer();
25
+ return new Uint8Array(buffer);
26
+ }
27
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../../src/structural/parsers/adapters/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,WAAmB,EACnB,OAA6B,EAAE;IAE/B,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,IAAI,kBAAkB,CAAC;IACvD,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,WAAW,OAAO,CAAC;IAE1C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,8CAA8C,GAAG,UAAU,QAAQ,CAAC,MAAM,GAAG,CAC9E,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Node.js adapter for loading tree-sitter grammar WASM files.
3
+ *
4
+ * Reads WASM bytes from the filesystem. Grammar resolution order:
5
+ * 1. `tree-sitter-wasms` package (if installed as optional peer)
6
+ * 2. `@gitwand/core` local assets directory (packages/core/assets/grammars/)
7
+ */
8
+ /**
9
+ * Resolve the filesystem path to a grammar WASM file.
10
+ *
11
+ * @param grammarName - e.g. "tree-sitter-typescript"
12
+ */
13
+ export declare function resolveGrammarPath(grammarName: string): string;
14
+ /**
15
+ * Load grammar WASM bytes from the Node.js filesystem.
16
+ */
17
+ export declare function loadGrammarBytes(grammarName: string): Promise<Uint8Array>;
18
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../../src/structural/parsers/adapters/node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAe9D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAI/E"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Node.js adapter for loading tree-sitter grammar WASM files.
3
+ *
4
+ * Reads WASM bytes from the filesystem. Grammar resolution order:
5
+ * 1. `tree-sitter-wasms` package (if installed as optional peer)
6
+ * 2. `@gitwand/core` local assets directory (packages/core/assets/grammars/)
7
+ */
8
+ import { readFile } from "node:fs/promises";
9
+ import { createRequire } from "node:module";
10
+ import { dirname, resolve } from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+ const _require = createRequire(import.meta.url);
13
+ /**
14
+ * Resolve the filesystem path to a grammar WASM file.
15
+ *
16
+ * @param grammarName - e.g. "tree-sitter-typescript"
17
+ */
18
+ export function resolveGrammarPath(grammarName) {
19
+ // 1. Try tree-sitter-wasms (optional peer) — publishes to out/ dir
20
+ try {
21
+ const pkgJson = _require.resolve("tree-sitter-wasms/package.json");
22
+ const pkgDir = dirname(pkgJson);
23
+ return resolve(pkgDir, "out", `${grammarName}.wasm`);
24
+ }
25
+ catch {
26
+ // tree-sitter-wasms not installed
27
+ }
28
+ // 2. Fallback: local assets directory (four levels up from this file)
29
+ // __file__ = packages/core/src/structural/parsers/adapters/node.ts
30
+ // target = packages/core/assets/grammars/
31
+ const thisDir = dirname(fileURLToPath(import.meta.url));
32
+ return resolve(thisDir, "../../../../../assets/grammars", `${grammarName}.wasm`);
33
+ }
34
+ /**
35
+ * Load grammar WASM bytes from the Node.js filesystem.
36
+ */
37
+ export async function loadGrammarBytes(grammarName) {
38
+ const grammarPath = resolveGrammarPath(grammarName);
39
+ const buf = await readFile(grammarPath);
40
+ return new Uint8Array(buf);
41
+ }
42
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../../../src/structural/parsers/adapters/node.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,mEAAmE;IACnE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,WAAW,OAAO,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;IAED,sEAAsE;IACtE,sEAAsE;IACtE,+CAA+C;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,OAAO,OAAO,CAAC,OAAO,EAAE,gCAAgC,EAAE,GAAG,WAAW,OAAO,CAAC,CAAC;AACnF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,WAAmB;IACxD,MAAM,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC;IACxC,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Tauri adapter for loading tree-sitter grammar WASM files.
3
+ *
4
+ * Uses `window.__TAURI_INTERNALS__.convertFileSrc` (Tauri v2) to convert a
5
+ * local asset path into a fetch-able asset:// URL, then loads via fetch.
6
+ *
7
+ * Grammar WASM files must be included in the Tauri bundle under the path
8
+ * specified by `grammarDir` (default: "/assets/grammars" relative to the
9
+ * Tauri resource directory).
10
+ */
11
+ export interface TauriLoaderOptions {
12
+ /**
13
+ * Absolute path to the directory containing grammar WASM files inside
14
+ * the Tauri resource bundle.
15
+ * Defaults to "/assets/grammars".
16
+ */
17
+ grammarDir?: string;
18
+ }
19
+ /**
20
+ * Load grammar WASM bytes in a Tauri webview context.
21
+ *
22
+ * @param grammarName - e.g. "tree-sitter-typescript"
23
+ * @param opts - Tauri-specific options
24
+ */
25
+ export declare function loadGrammarBytes(grammarName: string, opts?: TauriLoaderOptions): Promise<Uint8Array>;
26
+ //# sourceMappingURL=tauri.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tauri.d.ts","sourceRoot":"","sources":["../../../../src/structural/parsers/adapters/tauri.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,UAAU,CAAC,CAuBrB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Tauri adapter for loading tree-sitter grammar WASM files.
3
+ *
4
+ * Uses `window.__TAURI_INTERNALS__.convertFileSrc` (Tauri v2) to convert a
5
+ * local asset path into a fetch-able asset:// URL, then loads via fetch.
6
+ *
7
+ * Grammar WASM files must be included in the Tauri bundle under the path
8
+ * specified by `grammarDir` (default: "/assets/grammars" relative to the
9
+ * Tauri resource directory).
10
+ */
11
+ /**
12
+ * Load grammar WASM bytes in a Tauri webview context.
13
+ *
14
+ * @param grammarName - e.g. "tree-sitter-typescript"
15
+ * @param opts - Tauri-specific options
16
+ */
17
+ export async function loadGrammarBytes(grammarName, opts = {}) {
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ const tauri = window.__TAURI_INTERNALS__;
20
+ if (typeof tauri?.convertFileSrc !== "function") {
21
+ throw new Error("[structural] Tauri adapter: __TAURI_INTERNALS__.convertFileSrc is not available. " +
22
+ "Ensure you are running inside a Tauri webview and using Tauri v2.");
23
+ }
24
+ const grammarDir = opts.grammarDir ?? "/assets/grammars";
25
+ const localPath = `${grammarDir}/${grammarName}.wasm`;
26
+ const url = tauri.convertFileSrc(localPath, "asset");
27
+ const response = await fetch(url);
28
+ if (!response.ok) {
29
+ throw new Error(`[structural] Failed to fetch grammar WASM via Tauri: ${localPath} (HTTP ${response.status})`);
30
+ }
31
+ const buffer = await response.arrayBuffer();
32
+ return new Uint8Array(buffer);
33
+ }
34
+ //# sourceMappingURL=tauri.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tauri.js","sourceRoot":"","sources":["../../../../src/structural/parsers/adapters/tauri.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,WAAmB,EACnB,OAA2B,EAAE;IAE7B,8DAA8D;IAC9D,MAAM,KAAK,GAAI,MAAc,CAAC,mBAAmB,CAAC;IAClD,IAAI,OAAO,KAAK,EAAE,cAAc,KAAK,UAAU,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,mFAAmF;YACjF,mEAAmE,CACtE,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,kBAAkB,CAAC;IACzD,MAAM,SAAS,GAAG,GAAG,UAAU,IAAI,WAAW,OAAO,CAAC;IACtD,MAAM,GAAG,GAAW,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAE7D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,wDAAwD,SAAS,UAAU,QAAQ,CAAC,MAAM,GAAG,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Language registry for the structural merge engine.
3
+ *
4
+ * Maps file extensions → language identifiers → tree-sitter grammar WASM names.
5
+ * Grammar WASM names correspond to the filenames published by `tree-sitter-wasms`.
6
+ */
7
+ export type SupportedLanguage = "typescript" | "tsx" | "javascript" | "jsx" | "python" | "go" | "rust";
8
+ export interface LanguageSpec {
9
+ /** Grammar WASM name as published in `tree-sitter-wasms/out/` */
10
+ grammarName: string;
11
+ /** File extensions handled by this language (lowercase, with dot) */
12
+ extensions: string[];
13
+ }
14
+ export declare const LANGUAGE_SPECS: Record<SupportedLanguage, LanguageSpec>;
15
+ /**
16
+ * Detect the language for a given file path.
17
+ * Returns `null` if the file extension is not supported.
18
+ */
19
+ export declare function languageForFile(filePath: string): SupportedLanguage | null;
20
+ /**
21
+ * Returns `true` if the file can be handled by the structural merge engine.
22
+ *
23
+ * Excludes TypeScript declaration files (`.d.ts`) — they have no implementation
24
+ * to merge. Excludes `.min.js` and other generated bundles via the generated-file
25
+ * detector in the main resolver pipeline.
26
+ */
27
+ export declare function isStructuralLanguage(filePath: string): boolean;
28
+ /**
29
+ * Return the grammar WASM name for a file, or `null` if not supported.
30
+ */
31
+ export declare function grammarNameForFile(filePath: string): string | null;
32
+ //# sourceMappingURL=languages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.d.ts","sourceRoot":"","sources":["../../../../src/structural/parsers/grammars/languages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,KAAK,GACL,YAAY,GACZ,KAAK,GACL,QAAQ,GACR,IAAI,GACJ,MAAM,CAAC;AAEX,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAID,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,iBAAiB,EAAE,YAAY,CA8BlE,CAAC;AAYF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAM1E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG9D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGlE"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Language registry for the structural merge engine.
3
+ *
4
+ * Maps file extensions → language identifiers → tree-sitter grammar WASM names.
5
+ * Grammar WASM names correspond to the filenames published by `tree-sitter-wasms`.
6
+ */
7
+ // ─── Language specs ───────────────────────────────────────────────────────────
8
+ export const LANGUAGE_SPECS = {
9
+ typescript: {
10
+ grammarName: "tree-sitter-typescript",
11
+ extensions: [".ts"],
12
+ },
13
+ tsx: {
14
+ grammarName: "tree-sitter-tsx",
15
+ extensions: [".tsx"],
16
+ },
17
+ javascript: {
18
+ grammarName: "tree-sitter-javascript",
19
+ extensions: [".js", ".mjs", ".cjs"],
20
+ },
21
+ jsx: {
22
+ // JSX is parsed by the JavaScript grammar (tree-sitter-javascript supports JSX natively)
23
+ grammarName: "tree-sitter-javascript",
24
+ extensions: [".jsx"],
25
+ },
26
+ python: {
27
+ grammarName: "tree-sitter-python",
28
+ extensions: [".py"],
29
+ },
30
+ go: {
31
+ grammarName: "tree-sitter-go",
32
+ extensions: [".go"],
33
+ },
34
+ rust: {
35
+ grammarName: "tree-sitter-rust",
36
+ extensions: [".rs"],
37
+ },
38
+ };
39
+ // ─── Extension → language lookup table ───────────────────────────────────────
40
+ const EXT_TO_LANGUAGE = new Map(Object.entries(LANGUAGE_SPECS).flatMap(([lang, spec]) => spec.extensions.map((ext) => [ext, lang])));
41
+ // ─── Public API ───────────────────────────────────────────────────────────────
42
+ /**
43
+ * Detect the language for a given file path.
44
+ * Returns `null` if the file extension is not supported.
45
+ */
46
+ export function languageForFile(filePath) {
47
+ const lower = filePath.toLowerCase();
48
+ for (const [ext, lang] of EXT_TO_LANGUAGE) {
49
+ if (lower.endsWith(ext))
50
+ return lang;
51
+ }
52
+ return null;
53
+ }
54
+ /**
55
+ * Returns `true` if the file can be handled by the structural merge engine.
56
+ *
57
+ * Excludes TypeScript declaration files (`.d.ts`) — they have no implementation
58
+ * to merge. Excludes `.min.js` and other generated bundles via the generated-file
59
+ * detector in the main resolver pipeline.
60
+ */
61
+ export function isStructuralLanguage(filePath) {
62
+ if (/\.d\.ts$/i.test(filePath))
63
+ return false;
64
+ return languageForFile(filePath) !== null;
65
+ }
66
+ /**
67
+ * Return the grammar WASM name for a file, or `null` if not supported.
68
+ */
69
+ export function grammarNameForFile(filePath) {
70
+ const lang = languageForFile(filePath);
71
+ return lang ? LANGUAGE_SPECS[lang].grammarName : null;
72
+ }
73
+ //# sourceMappingURL=languages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"languages.js","sourceRoot":"","sources":["../../../../src/structural/parsers/grammars/languages.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,iFAAiF;AAEjF,MAAM,CAAC,MAAM,cAAc,GAA4C;IACrE,UAAU,EAAE;QACV,WAAW,EAAE,wBAAwB;QACrC,UAAU,EAAE,CAAC,KAAK,CAAC;KACpB;IACD,GAAG,EAAE;QACH,WAAW,EAAE,iBAAiB;QAC9B,UAAU,EAAE,CAAC,MAAM,CAAC;KACrB;IACD,UAAU,EAAE;QACV,WAAW,EAAE,wBAAwB;QACrC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;KACpC;IACD,GAAG,EAAE;QACH,yFAAyF;QACzF,WAAW,EAAE,wBAAwB;QACrC,UAAU,EAAE,CAAC,MAAM,CAAC;KACrB;IACD,MAAM,EAAE;QACN,WAAW,EAAE,oBAAoB;QACjC,UAAU,EAAE,CAAC,KAAK,CAAC;KACpB;IACD,EAAE,EAAE;QACF,WAAW,EAAE,gBAAgB;QAC7B,UAAU,EAAE,CAAC,KAAK,CAAC;KACpB;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,kBAAkB;QAC/B,UAAU,EAAE,CAAC,KAAK,CAAC;KACpB;CACF,CAAC;AAEF,gFAAgF;AAEhF,MAAM,eAAe,GAAmC,IAAI,GAAG,CAC5D,MAAM,CAAC,OAAO,CAAC,cAAc,CAAyC,CAAC,OAAO,CAC7E,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAA+B,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CACzF,CACF,CAAC;AAEF,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,eAAe,EAAE,CAAC;QAC1C,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,eAAe,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,OAAO,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AACxD,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Grammar loaders for all structural-merge–supported languages.
3
+ *
4
+ * Uses the unified language registry from `languages.ts` to map file paths
5
+ * to the correct `tree-sitter-wasms` grammar WASM.
6
+ */
7
+ import { type Language, type LoaderOptions } from "../loader.js";
8
+ /** Load the TypeScript grammar. */
9
+ export declare function loadTypeScriptGrammar(opts?: LoaderOptions): Promise<Language | null>;
10
+ /** Load the TSX grammar. */
11
+ export declare function loadTsxGrammar(opts?: LoaderOptions): Promise<Language | null>;
12
+ /** Load the JavaScript grammar (also used for JSX). */
13
+ export declare function loadJavaScriptGrammar(opts?: LoaderOptions): Promise<Language | null>;
14
+ /** Load the Python grammar. */
15
+ export declare function loadPythonGrammar(opts?: LoaderOptions): Promise<Language | null>;
16
+ /** Load the Go grammar. */
17
+ export declare function loadGoGrammar(opts?: LoaderOptions): Promise<Language | null>;
18
+ /** Load the Rust grammar. */
19
+ export declare function loadRustGrammar(opts?: LoaderOptions): Promise<Language | null>;
20
+ /**
21
+ * Load the appropriate grammar for a given file path.
22
+ * Returns `null` if the file extension is not supported or the grammar WASM
23
+ * is unavailable.
24
+ */
25
+ export declare function loadGrammarForFile(filePath: string, opts?: LoaderOptions): Promise<Language | null>;
26
+ //# sourceMappingURL=ts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts.d.ts","sourceRoot":"","sources":["../../../../src/structural/parsers/grammars/ts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAe,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAK9E,mCAAmC;AACnC,wBAAsB,qBAAqB,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAE9F;AAED,4BAA4B;AAC5B,wBAAsB,cAAc,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAEvF;AAED,uDAAuD;AACvD,wBAAsB,qBAAqB,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAE9F;AAED,+BAA+B;AAC/B,wBAAsB,iBAAiB,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAE1F;AAED,2BAA2B;AAC3B,wBAAsB,aAAa,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAEtF;AAED,6BAA6B;AAC7B,wBAAsB,eAAe,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAExF;AAID;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAI1B"}