@ricsam/r5d-worker 0.0.137 → 0.0.139

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 (236) hide show
  1. package/README.md +4 -94
  2. package/dist/cjs/package.json +1 -1
  3. package/dist/mjs/main.mjs +46 -7543
  4. package/dist/mjs/package.json +1 -1
  5. package/dist/mjs/personal/action-scheduler.mjs +31 -0
  6. package/dist/mjs/personal/client.mjs +215 -0
  7. package/dist/mjs/personal/runtime.mjs +359 -0
  8. package/dist/mjs/personal/tcp.mjs +217 -0
  9. package/dist/mjs/runtime/adapter.mjs +42 -0
  10. package/dist/mjs/runtime/client.mjs +95 -0
  11. package/dist/mjs/runtime/daemon.mjs +131 -0
  12. package/dist/mjs/runtime/executor.mjs +436 -0
  13. package/dist/mjs/runtime/index.mjs +15 -0
  14. package/dist/mjs/runtime/protocol.mjs +139 -0
  15. package/dist/mjs/runtime/pty-host.mjs +156 -0
  16. package/dist/mjs/runtime/pty.mjs +127 -0
  17. package/dist/mjs/runtime/releases/artifacts.mjs +201 -0
  18. package/dist/mjs/runtime/releases/grants.mjs +93 -0
  19. package/dist/mjs/runtime/releases/main.mjs +101 -0
  20. package/dist/mjs/runtime/releases/manager.mjs +541 -0
  21. package/dist/mjs/runtime/releases/process.mjs +88 -0
  22. package/dist/mjs/runtime/releases/retirement.mjs +18 -0
  23. package/dist/mjs/runtime/releases/rpc-client.mjs +184 -0
  24. package/dist/mjs/runtime/releases/rpc-main.mjs +213 -0
  25. package/dist/mjs/runtime/releases/rpc-protocol.mjs +103 -0
  26. package/dist/mjs/runtime/storage.mjs +156 -0
  27. package/dist/mjs/runtime/workspace/artifacts.mjs +121 -0
  28. package/dist/mjs/runtime/workspace/authority.mjs +1355 -0
  29. package/dist/mjs/runtime/workspace/contracts.mjs +60 -0
  30. package/dist/mjs/runtime/workspace/file-write.mjs +23 -0
  31. package/dist/mjs/runtime/workspace/files.mjs +308 -0
  32. package/dist/mjs/runtime/workspace/http-body.mjs +45 -0
  33. package/dist/mjs/runtime/workspace/storage-client.mjs +59 -0
  34. package/dist/mjs/runtime/workspace/storage-wire.mjs +53 -0
  35. package/dist/types/main.d.ts +0 -1167
  36. package/dist/types/personal/action-scheduler.d.ts +23 -0
  37. package/dist/types/personal/client.d.ts +14 -0
  38. package/dist/types/personal/runtime.d.ts +121 -0
  39. package/dist/types/personal/tcp.d.ts +14 -0
  40. package/dist/types/runtime/client.d.ts +3 -1
  41. package/dist/types/runtime/executor.d.ts +6 -1
  42. package/dist/types/runtime/protocol.d.ts +176 -4
  43. package/dist/types/runtime/pty.d.ts +1 -0
  44. package/dist/types/runtime/releases/artifacts.d.ts +51 -0
  45. package/dist/types/runtime/releases/grants.d.ts +16 -0
  46. package/dist/types/runtime/releases/manager.d.ts +145 -0
  47. package/dist/types/runtime/releases/process.d.ts +14 -0
  48. package/dist/types/runtime/releases/retirement.d.ts +15 -0
  49. package/dist/types/runtime/releases/rpc-client.d.ts +52 -0
  50. package/dist/types/runtime/releases/rpc-main.d.ts +10 -0
  51. package/dist/types/runtime/releases/rpc-protocol.d.ts +1139 -0
  52. package/dist/types/runtime/workspace/artifacts.d.ts +30 -0
  53. package/dist/types/runtime/workspace/authority.d.ts +338 -0
  54. package/dist/types/runtime/workspace/contracts.d.ts +86 -0
  55. package/dist/types/runtime/workspace/file-write.d.ts +14 -0
  56. package/dist/types/runtime/workspace/files.d.ts +21 -0
  57. package/dist/types/runtime/workspace/http-body.d.ts +9 -0
  58. package/dist/types/runtime/workspace/storage-client.d.ts +23 -0
  59. package/dist/types/runtime/workspace/storage-wire.d.ts +138 -0
  60. package/package.json +8 -6
  61. package/dist/cjs/atomic-rename.cjs +0 -303
  62. package/dist/cjs/browser-upload.cjs +0 -73
  63. package/dist/cjs/cli-update.cjs +0 -108
  64. package/dist/cjs/command-launcher.cjs +0 -423
  65. package/dist/cjs/control-command-policy.cjs +0 -177
  66. package/dist/cjs/git-blob-hash.cjs +0 -41
  67. package/dist/cjs/git-identity.cjs +0 -39
  68. package/dist/cjs/git-process-environment.cjs +0 -133
  69. package/dist/cjs/inline-output.cjs +0 -62
  70. package/dist/cjs/main.cjs +0 -7517
  71. package/dist/cjs/managed-paths.cjs +0 -215
  72. package/dist/cjs/plan-lint.cjs +0 -165
  73. package/dist/cjs/plan-parser.cjs +0 -127
  74. package/dist/cjs/plan-paths.cjs +0 -53
  75. package/dist/cjs/port-forward-client.cjs +0 -206
  76. package/dist/cjs/process-tree.cjs +0 -117
  77. package/dist/cjs/project-checkout-garbage.cjs +0 -219
  78. package/dist/cjs/project-mirror-fetch-policy.cjs +0 -82
  79. package/dist/cjs/project-mirror-refs-token.cjs +0 -85
  80. package/dist/cjs/project-workspace-state.cjs +0 -972
  81. package/dist/cjs/project-worktrees.cjs +0 -1713
  82. package/dist/cjs/pty-output-coalescer.cjs +0 -87
  83. package/dist/cjs/recovery-journal-protocol.cjs +0 -56
  84. package/dist/cjs/recovery-journal-runtime.cjs +0 -133
  85. package/dist/cjs/recovery-journal-thread.cjs +0 -9
  86. package/dist/cjs/recovery-journal.cjs +0 -742
  87. package/dist/cjs/recovery-output-window.cjs +0 -77
  88. package/dist/cjs/recovery-protocol.cjs +0 -31
  89. package/dist/cjs/recovery-store.cjs +0 -252
  90. package/dist/cjs/registry-auth.cjs +0 -310
  91. package/dist/cjs/repository-transition-policy.cjs +0 -49
  92. package/dist/cjs/runtime-version.cjs +0 -88
  93. package/dist/cjs/session-file-mutations.cjs +0 -61
  94. package/dist/cjs/supervisor.cjs +0 -147
  95. package/dist/cjs/three-way-merge.cjs +0 -346
  96. package/dist/cjs/working-tree-mirror.cjs +0 -1872
  97. package/dist/cjs/workspace-automatic-sync-policy.cjs +0 -79
  98. package/dist/cjs/workspace-branch-incarnation-policy.cjs +0 -37
  99. package/dist/cjs/workspace-command-sync-policy.cjs +0 -112
  100. package/dist/cjs/workspace-command-targets.cjs +0 -63
  101. package/dist/cjs/workspace-filesystem-executor-thread.cjs +0 -36
  102. package/dist/cjs/workspace-filesystem-executor.cjs +0 -327
  103. package/dist/cjs/workspace-filesystem-job-types.cjs +0 -144
  104. package/dist/cjs/workspace-filesystem-jobs.cjs +0 -59
  105. package/dist/cjs/workspace-git-sync.cjs +0 -3595
  106. package/dist/cjs/workspace-hydration-ledger.cjs +0 -83
  107. package/dist/cjs/workspace-hydration-merge.cjs +0 -448
  108. package/dist/cjs/workspace-hydration-recovery-state.cjs +0 -53
  109. package/dist/cjs/workspace-incident-state.cjs +0 -37
  110. package/dist/cjs/workspace-merge-projection.cjs +0 -628
  111. package/dist/cjs/workspace-mount-boundary.cjs +0 -71
  112. package/dist/cjs/workspace-mount-hold-fence.cjs +0 -120
  113. package/dist/cjs/workspace-mutation-gate.cjs +0 -127
  114. package/dist/cjs/workspace-path-move.cjs +0 -195
  115. package/dist/cjs/workspace-preserve-only-policy.cjs +0 -36
  116. package/dist/cjs/workspace-project-config-policy.cjs +0 -53
  117. package/dist/cjs/workspace-projection-ledger.cjs +0 -81
  118. package/dist/cjs/workspace-publication-evidence.cjs +0 -46
  119. package/dist/cjs/workspace-sync-coalescer.cjs +0 -58
  120. package/dist/mjs/atomic-rename.mjs +0 -261
  121. package/dist/mjs/browser-upload.mjs +0 -42
  122. package/dist/mjs/command-launcher.mjs +0 -393
  123. package/dist/mjs/control-command-policy.mjs +0 -146
  124. package/dist/mjs/git-blob-hash.mjs +0 -16
  125. package/dist/mjs/git-identity.mjs +0 -15
  126. package/dist/mjs/git-process-environment.mjs +0 -105
  127. package/dist/mjs/inline-output.mjs +0 -37
  128. package/dist/mjs/managed-paths.mjs +0 -174
  129. package/dist/mjs/plan-lint.mjs +0 -129
  130. package/dist/mjs/plan-parser.mjs +0 -94
  131. package/dist/mjs/plan-paths.mjs +0 -25
  132. package/dist/mjs/port-forward-client.mjs +0 -172
  133. package/dist/mjs/project-checkout-garbage.mjs +0 -178
  134. package/dist/mjs/project-mirror-fetch-policy.mjs +0 -56
  135. package/dist/mjs/project-mirror-refs-token.mjs +0 -53
  136. package/dist/mjs/project-workspace-state.mjs +0 -937
  137. package/dist/mjs/project-worktrees.mjs +0 -1657
  138. package/dist/mjs/pty-output-coalescer.mjs +0 -61
  139. package/dist/mjs/recovery-journal-protocol.mjs +0 -30
  140. package/dist/mjs/recovery-journal-runtime.mjs +0 -112
  141. package/dist/mjs/recovery-journal-thread.mjs +0 -8
  142. package/dist/mjs/recovery-journal.mjs +0 -694
  143. package/dist/mjs/recovery-output-window.mjs +0 -53
  144. package/dist/mjs/recovery-protocol.mjs +0 -6
  145. package/dist/mjs/recovery-store.mjs +0 -217
  146. package/dist/mjs/registry-auth.mjs +0 -269
  147. package/dist/mjs/repository-transition-policy.mjs +0 -22
  148. package/dist/mjs/runtime-version.mjs +0 -54
  149. package/dist/mjs/session-file-mutations.mjs +0 -37
  150. package/dist/mjs/supervisor.mjs +0 -114
  151. package/dist/mjs/three-way-merge.mjs +0 -318
  152. package/dist/mjs/working-tree-mirror.mjs +0 -1817
  153. package/dist/mjs/workspace-automatic-sync-policy.mjs +0 -48
  154. package/dist/mjs/workspace-branch-incarnation-policy.mjs +0 -13
  155. package/dist/mjs/workspace-command-sync-policy.mjs +0 -84
  156. package/dist/mjs/workspace-command-targets.mjs +0 -37
  157. package/dist/mjs/workspace-filesystem-executor-thread.mjs +0 -38
  158. package/dist/mjs/workspace-filesystem-executor.mjs +0 -287
  159. package/dist/mjs/workspace-filesystem-job-types.mjs +0 -116
  160. package/dist/mjs/workspace-filesystem-jobs.mjs +0 -55
  161. package/dist/mjs/workspace-git-sync.mjs +0 -3553
  162. package/dist/mjs/workspace-hydration-ledger.mjs +0 -58
  163. package/dist/mjs/workspace-hydration-merge.mjs +0 -414
  164. package/dist/mjs/workspace-hydration-recovery-state.mjs +0 -29
  165. package/dist/mjs/workspace-incident-state.mjs +0 -12
  166. package/dist/mjs/workspace-merge-projection.mjs +0 -594
  167. package/dist/mjs/workspace-mount-boundary.mjs +0 -37
  168. package/dist/mjs/workspace-mount-hold-fence.mjs +0 -95
  169. package/dist/mjs/workspace-mutation-gate.mjs +0 -103
  170. package/dist/mjs/workspace-path-move.mjs +0 -160
  171. package/dist/mjs/workspace-preserve-only-policy.mjs +0 -11
  172. package/dist/mjs/workspace-project-config-policy.mjs +0 -27
  173. package/dist/mjs/workspace-projection-ledger.mjs +0 -57
  174. package/dist/mjs/workspace-publication-evidence.mjs +0 -21
  175. package/dist/mjs/workspace-sync-coalescer.mjs +0 -34
  176. package/dist/types/atomic-rename.d.ts +0 -78
  177. package/dist/types/browser-upload.d.ts +0 -7
  178. package/dist/types/command-launcher.d.ts +0 -104
  179. package/dist/types/control-command-policy.d.ts +0 -53
  180. package/dist/types/git-blob-hash.d.ts +0 -10
  181. package/dist/types/git-identity.d.ts +0 -9
  182. package/dist/types/git-process-environment.d.ts +0 -9
  183. package/dist/types/inline-output.d.ts +0 -3
  184. package/dist/types/managed-paths.d.ts +0 -19
  185. package/dist/types/plan-lint.d.ts +0 -16
  186. package/dist/types/plan-parser.d.ts +0 -38
  187. package/dist/types/plan-paths.d.ts +0 -36
  188. package/dist/types/port-forward-client.d.ts +0 -8
  189. package/dist/types/project-checkout-garbage.d.ts +0 -86
  190. package/dist/types/project-mirror-fetch-policy.d.ts +0 -84
  191. package/dist/types/project-mirror-refs-token.d.ts +0 -53
  192. package/dist/types/project-workspace-state.d.ts +0 -188
  193. package/dist/types/project-worktrees.d.ts +0 -397
  194. package/dist/types/pty-output-coalescer.d.ts +0 -20
  195. package/dist/types/recovery-journal-protocol.d.ts +0 -35
  196. package/dist/types/recovery-journal-runtime.d.ts +0 -12
  197. package/dist/types/recovery-journal-stall-fixture.d.ts +0 -1
  198. package/dist/types/recovery-journal-thread.d.ts +0 -1
  199. package/dist/types/recovery-journal.d.ts +0 -248
  200. package/dist/types/recovery-output-window.d.ts +0 -19
  201. package/dist/types/recovery-protocol.d.ts +0 -59
  202. package/dist/types/recovery-store.d.ts +0 -52
  203. package/dist/types/registry-auth.d.ts +0 -47
  204. package/dist/types/repository-transition-policy.d.ts +0 -26
  205. package/dist/types/runtime-version.d.ts +0 -1
  206. package/dist/types/session-file-mutations.d.ts +0 -22
  207. package/dist/types/supervisor-daemonized-fixture.d.ts +0 -1
  208. package/dist/types/supervisor-launcher-cleanup-fixture.d.ts +0 -1
  209. package/dist/types/supervisor-signal-fixture.d.ts +0 -1
  210. package/dist/types/supervisor.d.ts +0 -23
  211. package/dist/types/three-way-merge.d.ts +0 -77
  212. package/dist/types/working-tree-mirror.d.ts +0 -424
  213. package/dist/types/workspace-automatic-sync-policy.d.ts +0 -57
  214. package/dist/types/workspace-branch-incarnation-policy.d.ts +0 -14
  215. package/dist/types/workspace-command-sync-policy.d.ts +0 -57
  216. package/dist/types/workspace-command-targets.d.ts +0 -37
  217. package/dist/types/workspace-filesystem-executor-thread.d.ts +0 -1
  218. package/dist/types/workspace-filesystem-executor.d.ts +0 -123
  219. package/dist/types/workspace-filesystem-job-types.d.ts +0 -302
  220. package/dist/types/workspace-filesystem-jobs.d.ts +0 -7
  221. package/dist/types/workspace-git-sync.d.ts +0 -514
  222. package/dist/types/workspace-hydration-ledger.d.ts +0 -76
  223. package/dist/types/workspace-hydration-merge.d.ts +0 -103
  224. package/dist/types/workspace-hydration-recovery-state.d.ts +0 -10
  225. package/dist/types/workspace-incident-state.d.ts +0 -19
  226. package/dist/types/workspace-merge-projection.d.ts +0 -69
  227. package/dist/types/workspace-mount-boundary.d.ts +0 -10
  228. package/dist/types/workspace-mount-hold-fence.d.ts +0 -42
  229. package/dist/types/workspace-mutation-gate.d.ts +0 -42
  230. package/dist/types/workspace-path-move.d.ts +0 -21
  231. package/dist/types/workspace-preserve-only-policy.d.ts +0 -15
  232. package/dist/types/workspace-project-config-policy.d.ts +0 -48
  233. package/dist/types/workspace-projection-ledger.d.ts +0 -59
  234. package/dist/types/workspace-publication-evidence.d.ts +0 -17
  235. package/dist/types/workspace-sync-coalescer.d.ts +0 -28
  236. /package/dist/types/{credential-authority-lock-fixture.d.ts → runtime/releases/main.d.ts} +0 -0
@@ -1,114 +0,0 @@
1
- import { constants as osConstants } from "node:os";
2
- import { terminateProcessTree } from "./process-tree.mjs";
3
- const WORKER_RUNTIME_ENV = "R5D_WORKER_INTERNAL_RUNTIME";
4
- const WORKER_RELOAD_EXIT_CODE = 75;
5
- const WORKER_RECONNECT_EXIT_CODE = 76;
6
- const WORKER_CREDENTIAL_RESTART_EXIT_CODE = 77;
7
- const WORKER_RECONNECT_DELAY_MS = 2e3;
8
- const WORKER_RECONNECT_JITTER_MS = 3e3;
9
- const WORKER_RECONNECT_MAX_DELAY_MS = 3e4;
10
- const SUPERVISOR_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
11
- function defaultRuntimeSpawner(argv, options) {
12
- return Bun.spawn(argv, options);
13
- }
14
- function defaultRuntimeDelay(delayMs) {
15
- return new Promise((resolve) => setTimeout(resolve, delayMs));
16
- }
17
- function workerReconnectDelayMs(random = Math.random, attempt = 0) {
18
- const sample = Math.max(0, Math.min(1, random()));
19
- const exponent = Math.min(20, Math.max(0, Math.floor(attempt)));
20
- const ceiling = Math.min(WORKER_RECONNECT_MAX_DELAY_MS, (WORKER_RECONNECT_DELAY_MS + WORKER_RECONNECT_JITTER_MS) * 2 ** exponent);
21
- const floor = Math.min(WORKER_RECONNECT_DELAY_MS * 2 ** exponent, ceiling * 0.4);
22
- return floor + Math.floor(sample * (ceiling - floor));
23
- }
24
- async function defaultRuntimeReaper(runtime) {
25
- await terminateProcessTree(runtime, { graceMs: 6e3 });
26
- }
27
- function isRetryableWorkerServerStatus(status) {
28
- return status === 408 || status === 429 || status >= 500;
29
- }
30
- function signalExitCode(signal) {
31
- return 128 + (osSignalNumber(signal) ?? 1);
32
- }
33
- function osSignalNumber(signal) {
34
- return osConstants.signals[signal];
35
- }
36
- async function superviseWorkerRuntime(argv, env = process.env, spawnRuntime = defaultRuntimeSpawner, waitBeforeReconnect = defaultRuntimeDelay, reapCredentialRuntime = defaultRuntimeReaper, reconnectDelay) {
37
- if (!process.argv[1]) {
38
- throw new Error("Cannot locate the r5d-worker entrypoint");
39
- }
40
- let reconnectAttempt = 0;
41
- while (true) {
42
- const runtime = spawnRuntime([process.execPath, process.argv[1], ...argv], {
43
- stdin: "inherit",
44
- stdout: "inherit",
45
- stderr: "inherit",
46
- detached: true,
47
- env: {
48
- ...env,
49
- [WORKER_RUNTIME_ENV]: "1"
50
- }
51
- });
52
- let receivedSignal;
53
- let resolveSignal;
54
- const signalReceived = new Promise((resolve) => {
55
- resolveSignal = resolve;
56
- });
57
- const handlers = SUPERVISOR_SIGNALS.map((signal) => {
58
- const handler = () => {
59
- if (receivedSignal) return;
60
- receivedSignal = signal;
61
- resolveSignal?.(signal);
62
- };
63
- process.on(signal, handler);
64
- return { signal, handler };
65
- });
66
- try {
67
- const outcome = await Promise.race([
68
- runtime.exited.then((exitCode2) => ({ type: "exit", exitCode: exitCode2 })),
69
- signalReceived.then((signal) => ({ type: "signal", signal }))
70
- ]);
71
- try {
72
- await reapCredentialRuntime(runtime);
73
- } catch (error) {
74
- process.stderr.write(
75
- `[r5d-worker] runtime restart/exit aborted because process-group reaping failed: ${error instanceof Error ? error.message : String(error)}
76
- `
77
- );
78
- return 1;
79
- }
80
- if (outcome.type === "signal" || receivedSignal) {
81
- return signalExitCode(outcome.type === "signal" ? outcome.signal : receivedSignal);
82
- }
83
- const { exitCode } = outcome;
84
- if (exitCode === WORKER_RELOAD_EXIT_CODE) {
85
- process.stdout.write("[r5d-worker] activating updated worker runtime\n");
86
- continue;
87
- }
88
- if (exitCode === WORKER_RECONNECT_EXIT_CODE) {
89
- const reconnectDelayMs = reconnectDelay?.() ?? workerReconnectDelayMs(Math.random, reconnectAttempt++);
90
- process.stderr.write(`[r5d-worker] reconnecting in ${reconnectDelayMs}ms
91
- `);
92
- await waitBeforeReconnect(reconnectDelayMs);
93
- if (receivedSignal) return signalExitCode(receivedSignal);
94
- continue;
95
- }
96
- return exitCode;
97
- } finally {
98
- const processEvents = process;
99
- for (const { signal, handler } of handlers) processEvents.off(signal, handler);
100
- }
101
- }
102
- }
103
- export {
104
- WORKER_CREDENTIAL_RESTART_EXIT_CODE,
105
- WORKER_RECONNECT_DELAY_MS,
106
- WORKER_RECONNECT_EXIT_CODE,
107
- WORKER_RECONNECT_JITTER_MS,
108
- WORKER_RECONNECT_MAX_DELAY_MS,
109
- WORKER_RELOAD_EXIT_CODE,
110
- WORKER_RUNTIME_ENV,
111
- isRetryableWorkerServerStatus,
112
- superviseWorkerRuntime,
113
- workerReconnectDelayMs
114
- };
@@ -1,318 +0,0 @@
1
- const BINARY_PROBE_BYTES = 8e3;
2
- const DEFAULT_MAX_LINES = 1e6;
3
- const DEFAULT_MAX_EDIT_DISTANCE = 2e4;
4
- const DEFAULT_MAX_ALIGNMENT_CELLS = 1e8;
5
- const DEFAULT_MAX_DIFF_WORK = 5e7;
6
- const NEWLINE = 10;
7
- const NO_COMMON_LINES = /* @__PURE__ */ Symbol("no-common-lines");
8
- function isBinaryContent(content) {
9
- return content.subarray(0, BINARY_PROBE_BYTES).includes(0);
10
- }
11
- class LineTable {
12
- ids = /* @__PURE__ */ new Map();
13
- lines = [];
14
- intern(line) {
15
- const key = line.toString("latin1");
16
- let id = this.ids.get(key);
17
- if (id === void 0) {
18
- id = this.lines.length;
19
- this.ids.set(key, id);
20
- this.lines.push(line);
21
- }
22
- return id;
23
- }
24
- }
25
- function splitLines(content, table, maxLines) {
26
- let count = 0;
27
- for (let offset = 0; offset < content.length; ) {
28
- const newline = content.indexOf(NEWLINE, offset);
29
- count += 1;
30
- if (count > maxLines) return null;
31
- offset = newline < 0 ? content.length : newline + 1;
32
- }
33
- const ids = new Int32Array(count);
34
- let index = 0;
35
- for (let offset = 0; offset < content.length; ) {
36
- const newline = content.indexOf(NEWLINE, offset);
37
- const end = newline < 0 ? content.length : newline + 1;
38
- ids[index] = table.intern(content.subarray(offset, end));
39
- index += 1;
40
- offset = end;
41
- }
42
- return ids;
43
- }
44
- function findSplit(a, a0, a1, b, b0, b1, forward, backward, maxEditDistance, budget) {
45
- const n = a1 - a0;
46
- const m = b1 - b0;
47
- const maxD = Math.ceil((n + m) / 2);
48
- const offset = maxD;
49
- const length = 2 * maxD + 2;
50
- forward.fill(-1, 0, length);
51
- backward.fill(-1, 0, length);
52
- forward[offset + 1] = 0;
53
- backward[offset + 1] = 0;
54
- const delta = n - m;
55
- const meetOnForward = (delta & 1) !== 0;
56
- let forwardStart = 0;
57
- let forwardEnd = 0;
58
- let backwardStart = 0;
59
- let backwardEnd = 0;
60
- for (let d = 0; d < maxD; d += 1) {
61
- if (2 * d > maxEditDistance) return null;
62
- budget.remaining -= 2 * (2 * d + 1);
63
- if (budget.remaining < 0) return null;
64
- for (let k = -d + forwardStart; k <= d - forwardEnd; k += 2) {
65
- const kIndex = offset + k;
66
- let x = k === -d || k !== d && forward[kIndex - 1] < forward[kIndex + 1] ? forward[kIndex + 1] : forward[kIndex - 1] + 1;
67
- let y = x - k;
68
- const snakeStart = x;
69
- while (x < n && y < m && a[a0 + x] === b[b0 + y]) {
70
- x += 1;
71
- y += 1;
72
- }
73
- budget.remaining -= x - snakeStart;
74
- forward[kIndex] = x;
75
- if (x > n) forwardEnd += 2;
76
- else if (y > m) forwardStart += 2;
77
- else if (meetOnForward) {
78
- const reverseIndex = offset + delta - k;
79
- if (reverseIndex >= 0 && reverseIndex < length && backward[reverseIndex] !== -1 && x >= n - backward[reverseIndex]) {
80
- return [a0 + x, b0 + y];
81
- }
82
- }
83
- }
84
- for (let k = -d + backwardStart; k <= d - backwardEnd; k += 2) {
85
- const kIndex = offset + k;
86
- let x = k === -d || k !== d && backward[kIndex - 1] < backward[kIndex + 1] ? backward[kIndex + 1] : backward[kIndex - 1] + 1;
87
- let y = x - k;
88
- const snakeStart = x;
89
- while (x < n && y < m && a[a1 - x - 1] === b[b1 - y - 1]) {
90
- x += 1;
91
- y += 1;
92
- }
93
- budget.remaining -= x - snakeStart;
94
- backward[kIndex] = x;
95
- if (x > n) backwardEnd += 2;
96
- else if (y > m) backwardStart += 2;
97
- else if (!meetOnForward) {
98
- const forwardIndex = offset + delta - k;
99
- if (forwardIndex >= 0 && forwardIndex < length && forward[forwardIndex] !== -1) {
100
- const forwardX = forward[forwardIndex];
101
- if (forwardX >= n - x) return [a0 + forwardX, b0 + forwardX - (forwardIndex - offset)];
102
- }
103
- }
104
- }
105
- }
106
- return n + m > maxEditDistance ? null : NO_COMMON_LINES;
107
- }
108
- function diffLines(a, b, options = {}) {
109
- const maxEditDistance = options.maxEditDistance ?? DEFAULT_MAX_EDIT_DISTANCE;
110
- if (maxEditDistance < 0) return null;
111
- const budget = { remaining: options.maxWork ?? DEFAULT_MAX_DIFF_WORK };
112
- const scratchLength = a.length + b.length + 4;
113
- const forward = new Int32Array(scratchLength);
114
- const backward = new Int32Array(scratchLength);
115
- const hunks = [];
116
- const stack = [0, a.length, 0, b.length];
117
- let topLevel = true;
118
- while (stack.length > 0) {
119
- let b1 = stack.pop();
120
- let b0 = stack.pop();
121
- let a1 = stack.pop();
122
- let a0 = stack.pop();
123
- while (a0 < a1 && b0 < b1 && a[a0] === b[b0]) {
124
- a0 += 1;
125
- b0 += 1;
126
- }
127
- while (a0 < a1 && b0 < b1 && a[a1 - 1] === b[b1 - 1]) {
128
- a1 -= 1;
129
- b1 -= 1;
130
- }
131
- if (a0 === a1 && b0 === b1) continue;
132
- let noCommonLines = a0 === a1 || b0 === b1;
133
- if (!noCommonLines && topLevel) {
134
- const seen = /* @__PURE__ */ new Set();
135
- for (let index = a0; index < a1; index += 1) seen.add(a[index]);
136
- noCommonLines = true;
137
- for (let index = b0; index < b1; index += 1) {
138
- if (seen.has(b[index])) {
139
- noCommonLines = false;
140
- break;
141
- }
142
- }
143
- if (noCommonLines && a1 - a0 + (b1 - b0) > maxEditDistance) return null;
144
- }
145
- topLevel = false;
146
- const split = noCommonLines ? NO_COMMON_LINES : findSplit(a, a0, a1, b, b0, b1, forward, backward, maxEditDistance, budget);
147
- if (split === null) return null;
148
- if (split === NO_COMMON_LINES) {
149
- const previous = hunks[hunks.length - 1];
150
- if (previous && previous.aEnd === a0 && previous.bEnd === b0) {
151
- previous.aEnd = a1;
152
- previous.bEnd = b1;
153
- } else hunks.push({ aStart: a0, aEnd: a1, bStart: b0, bEnd: b1 });
154
- continue;
155
- }
156
- stack.push(split[0], a1, split[1], b1, a0, split[0], b0, split[1]);
157
- }
158
- return hunks;
159
- }
160
- function analyzeAlignment(a, b, lcsLength, maxCells) {
161
- const n = a.length;
162
- const m = b.length;
163
- const kMin = lcsLength - m;
164
- const kMax = n - lcsLength;
165
- const width = kMax - kMin + 1;
166
- const certain = new Int32Array(n).fill(-1);
167
- const ambiguous = new Uint8Array(n);
168
- if (n === 0) return { certain, ambiguous };
169
- if ((n + 1) * width > maxCells) return null;
170
- const computeSuffixRow = (i, next, out) => {
171
- for (let index = width - 1; index >= 0; index -= 1) {
172
- const j = i - kMax + index;
173
- if (j < 0 || j >= m) {
174
- out[index] = 0;
175
- continue;
176
- }
177
- const down = index > 0 ? next[index - 1] : 0;
178
- const right = index + 1 < width ? out[index + 1] : 0;
179
- const diagonal = next[index] + (a[i] === b[j] ? 1 : 0);
180
- out[index] = down > right ? down > diagonal ? down : diagonal : right > diagonal ? right : diagonal;
181
- }
182
- };
183
- const computePrefixRow = (i, previous, out) => {
184
- for (let index = 0; index < width; index += 1) {
185
- const j = i - kMax + index;
186
- if (j <= 0 || j > m || i === 0) {
187
- out[index] = 0;
188
- continue;
189
- }
190
- const up = index + 1 < width ? previous[index + 1] : 0;
191
- const left = index > 0 ? out[index - 1] : 0;
192
- const diagonal = previous[index] + (a[i - 1] === b[j - 1] ? 1 : 0);
193
- out[index] = up > left ? up > diagonal ? up : diagonal : left > diagonal ? left : diagonal;
194
- }
195
- };
196
- const blockSize = Math.ceil(Math.sqrt(n + 1));
197
- const checkpoints = /* @__PURE__ */ new Map();
198
- let suffixNext = new Int32Array(width);
199
- let suffixCurrent = new Int32Array(width);
200
- checkpoints.set(n, new Int32Array(width));
201
- for (let i = n - 1; i >= 0; i -= 1) {
202
- computeSuffixRow(i, suffixNext, suffixCurrent);
203
- if (i % blockSize === 0) checkpoints.set(i, suffixCurrent.slice());
204
- [suffixNext, suffixCurrent] = [suffixCurrent, suffixNext];
205
- }
206
- const block = Array.from({ length: blockSize + 1 }, () => new Int32Array(width));
207
- let prefixPrevious = new Int32Array(width);
208
- let prefixCurrent = new Int32Array(width);
209
- for (let blockStart = 0; blockStart < n; blockStart += blockSize) {
210
- const blockEnd = Math.min(blockStart + blockSize, n);
211
- block[blockEnd - blockStart] = checkpoints.get(blockEnd);
212
- for (let i = blockEnd - 1; i > blockStart; i -= 1) computeSuffixRow(i, block[i + 1 - blockStart], block[i - blockStart]);
213
- for (let i = blockStart; i < blockEnd; i += 1) {
214
- computePrefixRow(i, prefixPrevious, prefixCurrent);
215
- const suffix = block[i + 1 - blockStart];
216
- let bestDeletion = 0;
217
- let matches = 0;
218
- let partner = -1;
219
- for (let index = 0; index < width; index += 1) {
220
- const j = i - kMax + index;
221
- if (j < 0 || j > m) continue;
222
- const prefix = prefixCurrent[index];
223
- const deleted = prefix + (index > 0 ? suffix[index - 1] : 0);
224
- if (deleted > bestDeletion) bestDeletion = deleted;
225
- if (j < m && a[i] === b[j] && prefix + 1 + suffix[index] === lcsLength) {
226
- matches += 1;
227
- partner = j;
228
- }
229
- }
230
- if (matches === 1 && bestDeletion < lcsLength) certain[i] = partner;
231
- else if (matches > 0) ambiguous[i] = 1;
232
- [prefixPrevious, prefixCurrent] = [prefixCurrent, prefixPrevious];
233
- }
234
- }
235
- return { certain, ambiguous };
236
- }
237
- function rangesEqual(a, aStart, aEnd, b, bStart, bEnd) {
238
- if (aEnd - aStart !== bEnd - bStart) return false;
239
- for (let offset = 0; offset < aEnd - aStart; offset += 1) {
240
- if (a[aStart + offset] !== b[bStart + offset]) return false;
241
- }
242
- return true;
243
- }
244
- function anyAmbiguous(flags, start, end) {
245
- for (let index = start; index < end; index += 1) if (flags[index]) return true;
246
- return false;
247
- }
248
- function sideAlignment(base, side, options) {
249
- const maxEditDistance = Math.min(options.maxEditDistance, Math.floor(options.maxAlignmentCells / (base.length + 1)) - 1);
250
- const hunks = diffLines(base, side, { maxEditDistance, maxWork: options.maxDiffWork });
251
- if (!hunks) return null;
252
- let deleted = 0;
253
- for (const hunk of hunks) deleted += hunk.aEnd - hunk.aStart;
254
- return analyzeAlignment(base, side, base.length - deleted, options.maxAlignmentCells);
255
- }
256
- function mergeThreeWay(base, ours, theirs, options = {}) {
257
- if (ours.equals(base)) return { kind: "clean", content: theirs };
258
- if (theirs.equals(base)) return { kind: "clean", content: ours };
259
- if (ours.equals(theirs)) return { kind: "clean", content: ours };
260
- if (isBinaryContent(base) || isBinaryContent(ours) || isBinaryContent(theirs)) return { kind: "conflict", conflicts: 1 };
261
- const maxLines = options.maxLines ?? DEFAULT_MAX_LINES;
262
- const bounds = {
263
- maxEditDistance: options.maxEditDistance ?? DEFAULT_MAX_EDIT_DISTANCE,
264
- maxAlignmentCells: options.maxAlignmentCells ?? DEFAULT_MAX_ALIGNMENT_CELLS,
265
- maxDiffWork: options.maxDiffWork ?? DEFAULT_MAX_DIFF_WORK
266
- };
267
- const table = new LineTable();
268
- const baseLines = splitLines(base, table, maxLines);
269
- const oursLines = splitLines(ours, table, maxLines);
270
- const theirsLines = splitLines(theirs, table, maxLines);
271
- if (!baseLines || !oursLines || !theirsLines) return { kind: "conflict", conflicts: 1 };
272
- const oursAlignment = sideAlignment(baseLines, oursLines, bounds);
273
- const theirsAlignment = sideAlignment(baseLines, theirsLines, bounds);
274
- if (!oursAlignment || !theirsAlignment) return { kind: "conflict", conflicts: 1 };
275
- const oursMatch = oursAlignment.certain;
276
- const theirsMatch = theirsAlignment.certain;
277
- const output = [];
278
- let conflicts = 0;
279
- let i = 0;
280
- let o = 0;
281
- let t = 0;
282
- for (; ; ) {
283
- while (i < baseLines.length && oursMatch[i] === o && theirsMatch[i] === t) {
284
- output.push(table.lines[baseLines[i]]);
285
- i += 1;
286
- o += 1;
287
- t += 1;
288
- }
289
- if (i === baseLines.length && o === oursLines.length && t === theirsLines.length) break;
290
- let j = i;
291
- while (j < baseLines.length && (oursMatch[j] < 0 || theirsMatch[j] < 0)) j += 1;
292
- const oursEnd = j < baseLines.length ? oursMatch[j] : oursLines.length;
293
- const theirsEnd = j < baseLines.length ? theirsMatch[j] : theirsLines.length;
294
- if (rangesEqual(baseLines, i, j, oursLines, o, oursEnd)) {
295
- for (let index = t; index < theirsEnd; index += 1) output.push(table.lines[theirsLines[index]]);
296
- } else if (rangesEqual(baseLines, i, j, theirsLines, t, theirsEnd)) {
297
- for (let index = o; index < oursEnd; index += 1) output.push(table.lines[oursLines[index]]);
298
- } else if (rangesEqual(oursLines, o, oursEnd, theirsLines, t, theirsEnd) && // Git compares its hunks, not the region text: the same text reached by
299
- // differently shaped hunks still conflicts there, so only a region whose
300
- // alignment is unique on both sides is safely the same change.
301
- !anyAmbiguous(oursAlignment.ambiguous, i, j) && !anyAmbiguous(theirsAlignment.ambiguous, i, j)) {
302
- for (let index = o; index < oursEnd; index += 1) output.push(table.lines[oursLines[index]]);
303
- } else conflicts += 1;
304
- i = j;
305
- o = oursEnd;
306
- t = theirsEnd;
307
- }
308
- if (conflicts > 0) return { kind: "conflict", conflicts };
309
- return { kind: "clean", content: Buffer.concat(output) };
310
- }
311
- const threeWayMergeTestHarness = { diffLines, analyzeAlignment };
312
- export {
313
- analyzeAlignment,
314
- diffLines,
315
- isBinaryContent,
316
- mergeThreeWay,
317
- threeWayMergeTestHarness
318
- };