@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.
- package/README.md +4 -94
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/main.mjs +46 -7543
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/personal/action-scheduler.mjs +31 -0
- package/dist/mjs/personal/client.mjs +215 -0
- package/dist/mjs/personal/runtime.mjs +359 -0
- package/dist/mjs/personal/tcp.mjs +217 -0
- package/dist/mjs/runtime/adapter.mjs +42 -0
- package/dist/mjs/runtime/client.mjs +95 -0
- package/dist/mjs/runtime/daemon.mjs +131 -0
- package/dist/mjs/runtime/executor.mjs +436 -0
- package/dist/mjs/runtime/index.mjs +15 -0
- package/dist/mjs/runtime/protocol.mjs +139 -0
- package/dist/mjs/runtime/pty-host.mjs +156 -0
- package/dist/mjs/runtime/pty.mjs +127 -0
- package/dist/mjs/runtime/releases/artifacts.mjs +201 -0
- package/dist/mjs/runtime/releases/grants.mjs +93 -0
- package/dist/mjs/runtime/releases/main.mjs +101 -0
- package/dist/mjs/runtime/releases/manager.mjs +541 -0
- package/dist/mjs/runtime/releases/process.mjs +88 -0
- package/dist/mjs/runtime/releases/retirement.mjs +18 -0
- package/dist/mjs/runtime/releases/rpc-client.mjs +184 -0
- package/dist/mjs/runtime/releases/rpc-main.mjs +213 -0
- package/dist/mjs/runtime/releases/rpc-protocol.mjs +103 -0
- package/dist/mjs/runtime/storage.mjs +156 -0
- package/dist/mjs/runtime/workspace/artifacts.mjs +121 -0
- package/dist/mjs/runtime/workspace/authority.mjs +1355 -0
- package/dist/mjs/runtime/workspace/contracts.mjs +60 -0
- package/dist/mjs/runtime/workspace/file-write.mjs +23 -0
- package/dist/mjs/runtime/workspace/files.mjs +308 -0
- package/dist/mjs/runtime/workspace/http-body.mjs +45 -0
- package/dist/mjs/runtime/workspace/storage-client.mjs +59 -0
- package/dist/mjs/runtime/workspace/storage-wire.mjs +53 -0
- package/dist/types/main.d.ts +0 -1167
- package/dist/types/personal/action-scheduler.d.ts +23 -0
- package/dist/types/personal/client.d.ts +14 -0
- package/dist/types/personal/runtime.d.ts +121 -0
- package/dist/types/personal/tcp.d.ts +14 -0
- package/dist/types/runtime/client.d.ts +3 -1
- package/dist/types/runtime/executor.d.ts +6 -1
- package/dist/types/runtime/protocol.d.ts +176 -4
- package/dist/types/runtime/pty.d.ts +1 -0
- package/dist/types/runtime/releases/artifacts.d.ts +51 -0
- package/dist/types/runtime/releases/grants.d.ts +16 -0
- package/dist/types/runtime/releases/manager.d.ts +145 -0
- package/dist/types/runtime/releases/process.d.ts +14 -0
- package/dist/types/runtime/releases/retirement.d.ts +15 -0
- package/dist/types/runtime/releases/rpc-client.d.ts +52 -0
- package/dist/types/runtime/releases/rpc-main.d.ts +10 -0
- package/dist/types/runtime/releases/rpc-protocol.d.ts +1139 -0
- package/dist/types/runtime/workspace/artifacts.d.ts +30 -0
- package/dist/types/runtime/workspace/authority.d.ts +338 -0
- package/dist/types/runtime/workspace/contracts.d.ts +86 -0
- package/dist/types/runtime/workspace/file-write.d.ts +14 -0
- package/dist/types/runtime/workspace/files.d.ts +21 -0
- package/dist/types/runtime/workspace/http-body.d.ts +9 -0
- package/dist/types/runtime/workspace/storage-client.d.ts +23 -0
- package/dist/types/runtime/workspace/storage-wire.d.ts +138 -0
- package/package.json +8 -6
- package/dist/cjs/atomic-rename.cjs +0 -303
- package/dist/cjs/browser-upload.cjs +0 -73
- package/dist/cjs/cli-update.cjs +0 -108
- package/dist/cjs/command-launcher.cjs +0 -423
- package/dist/cjs/control-command-policy.cjs +0 -177
- package/dist/cjs/git-blob-hash.cjs +0 -41
- package/dist/cjs/git-identity.cjs +0 -39
- package/dist/cjs/git-process-environment.cjs +0 -133
- package/dist/cjs/inline-output.cjs +0 -62
- package/dist/cjs/main.cjs +0 -7517
- package/dist/cjs/managed-paths.cjs +0 -215
- package/dist/cjs/plan-lint.cjs +0 -165
- package/dist/cjs/plan-parser.cjs +0 -127
- package/dist/cjs/plan-paths.cjs +0 -53
- package/dist/cjs/port-forward-client.cjs +0 -206
- package/dist/cjs/process-tree.cjs +0 -117
- package/dist/cjs/project-checkout-garbage.cjs +0 -219
- package/dist/cjs/project-mirror-fetch-policy.cjs +0 -82
- package/dist/cjs/project-mirror-refs-token.cjs +0 -85
- package/dist/cjs/project-workspace-state.cjs +0 -972
- package/dist/cjs/project-worktrees.cjs +0 -1713
- package/dist/cjs/pty-output-coalescer.cjs +0 -87
- package/dist/cjs/recovery-journal-protocol.cjs +0 -56
- package/dist/cjs/recovery-journal-runtime.cjs +0 -133
- package/dist/cjs/recovery-journal-thread.cjs +0 -9
- package/dist/cjs/recovery-journal.cjs +0 -742
- package/dist/cjs/recovery-output-window.cjs +0 -77
- package/dist/cjs/recovery-protocol.cjs +0 -31
- package/dist/cjs/recovery-store.cjs +0 -252
- package/dist/cjs/registry-auth.cjs +0 -310
- package/dist/cjs/repository-transition-policy.cjs +0 -49
- package/dist/cjs/runtime-version.cjs +0 -88
- package/dist/cjs/session-file-mutations.cjs +0 -61
- package/dist/cjs/supervisor.cjs +0 -147
- package/dist/cjs/three-way-merge.cjs +0 -346
- package/dist/cjs/working-tree-mirror.cjs +0 -1872
- package/dist/cjs/workspace-automatic-sync-policy.cjs +0 -79
- package/dist/cjs/workspace-branch-incarnation-policy.cjs +0 -37
- package/dist/cjs/workspace-command-sync-policy.cjs +0 -112
- package/dist/cjs/workspace-command-targets.cjs +0 -63
- package/dist/cjs/workspace-filesystem-executor-thread.cjs +0 -36
- package/dist/cjs/workspace-filesystem-executor.cjs +0 -327
- package/dist/cjs/workspace-filesystem-job-types.cjs +0 -144
- package/dist/cjs/workspace-filesystem-jobs.cjs +0 -59
- package/dist/cjs/workspace-git-sync.cjs +0 -3595
- package/dist/cjs/workspace-hydration-ledger.cjs +0 -83
- package/dist/cjs/workspace-hydration-merge.cjs +0 -448
- package/dist/cjs/workspace-hydration-recovery-state.cjs +0 -53
- package/dist/cjs/workspace-incident-state.cjs +0 -37
- package/dist/cjs/workspace-merge-projection.cjs +0 -628
- package/dist/cjs/workspace-mount-boundary.cjs +0 -71
- package/dist/cjs/workspace-mount-hold-fence.cjs +0 -120
- package/dist/cjs/workspace-mutation-gate.cjs +0 -127
- package/dist/cjs/workspace-path-move.cjs +0 -195
- package/dist/cjs/workspace-preserve-only-policy.cjs +0 -36
- package/dist/cjs/workspace-project-config-policy.cjs +0 -53
- package/dist/cjs/workspace-projection-ledger.cjs +0 -81
- package/dist/cjs/workspace-publication-evidence.cjs +0 -46
- package/dist/cjs/workspace-sync-coalescer.cjs +0 -58
- package/dist/mjs/atomic-rename.mjs +0 -261
- package/dist/mjs/browser-upload.mjs +0 -42
- package/dist/mjs/command-launcher.mjs +0 -393
- package/dist/mjs/control-command-policy.mjs +0 -146
- package/dist/mjs/git-blob-hash.mjs +0 -16
- package/dist/mjs/git-identity.mjs +0 -15
- package/dist/mjs/git-process-environment.mjs +0 -105
- package/dist/mjs/inline-output.mjs +0 -37
- package/dist/mjs/managed-paths.mjs +0 -174
- package/dist/mjs/plan-lint.mjs +0 -129
- package/dist/mjs/plan-parser.mjs +0 -94
- package/dist/mjs/plan-paths.mjs +0 -25
- package/dist/mjs/port-forward-client.mjs +0 -172
- package/dist/mjs/project-checkout-garbage.mjs +0 -178
- package/dist/mjs/project-mirror-fetch-policy.mjs +0 -56
- package/dist/mjs/project-mirror-refs-token.mjs +0 -53
- package/dist/mjs/project-workspace-state.mjs +0 -937
- package/dist/mjs/project-worktrees.mjs +0 -1657
- package/dist/mjs/pty-output-coalescer.mjs +0 -61
- package/dist/mjs/recovery-journal-protocol.mjs +0 -30
- package/dist/mjs/recovery-journal-runtime.mjs +0 -112
- package/dist/mjs/recovery-journal-thread.mjs +0 -8
- package/dist/mjs/recovery-journal.mjs +0 -694
- package/dist/mjs/recovery-output-window.mjs +0 -53
- package/dist/mjs/recovery-protocol.mjs +0 -6
- package/dist/mjs/recovery-store.mjs +0 -217
- package/dist/mjs/registry-auth.mjs +0 -269
- package/dist/mjs/repository-transition-policy.mjs +0 -22
- package/dist/mjs/runtime-version.mjs +0 -54
- package/dist/mjs/session-file-mutations.mjs +0 -37
- package/dist/mjs/supervisor.mjs +0 -114
- package/dist/mjs/three-way-merge.mjs +0 -318
- package/dist/mjs/working-tree-mirror.mjs +0 -1817
- package/dist/mjs/workspace-automatic-sync-policy.mjs +0 -48
- package/dist/mjs/workspace-branch-incarnation-policy.mjs +0 -13
- package/dist/mjs/workspace-command-sync-policy.mjs +0 -84
- package/dist/mjs/workspace-command-targets.mjs +0 -37
- package/dist/mjs/workspace-filesystem-executor-thread.mjs +0 -38
- package/dist/mjs/workspace-filesystem-executor.mjs +0 -287
- package/dist/mjs/workspace-filesystem-job-types.mjs +0 -116
- package/dist/mjs/workspace-filesystem-jobs.mjs +0 -55
- package/dist/mjs/workspace-git-sync.mjs +0 -3553
- package/dist/mjs/workspace-hydration-ledger.mjs +0 -58
- package/dist/mjs/workspace-hydration-merge.mjs +0 -414
- package/dist/mjs/workspace-hydration-recovery-state.mjs +0 -29
- package/dist/mjs/workspace-incident-state.mjs +0 -12
- package/dist/mjs/workspace-merge-projection.mjs +0 -594
- package/dist/mjs/workspace-mount-boundary.mjs +0 -37
- package/dist/mjs/workspace-mount-hold-fence.mjs +0 -95
- package/dist/mjs/workspace-mutation-gate.mjs +0 -103
- package/dist/mjs/workspace-path-move.mjs +0 -160
- package/dist/mjs/workspace-preserve-only-policy.mjs +0 -11
- package/dist/mjs/workspace-project-config-policy.mjs +0 -27
- package/dist/mjs/workspace-projection-ledger.mjs +0 -57
- package/dist/mjs/workspace-publication-evidence.mjs +0 -21
- package/dist/mjs/workspace-sync-coalescer.mjs +0 -34
- package/dist/types/atomic-rename.d.ts +0 -78
- package/dist/types/browser-upload.d.ts +0 -7
- package/dist/types/command-launcher.d.ts +0 -104
- package/dist/types/control-command-policy.d.ts +0 -53
- package/dist/types/git-blob-hash.d.ts +0 -10
- package/dist/types/git-identity.d.ts +0 -9
- package/dist/types/git-process-environment.d.ts +0 -9
- package/dist/types/inline-output.d.ts +0 -3
- package/dist/types/managed-paths.d.ts +0 -19
- package/dist/types/plan-lint.d.ts +0 -16
- package/dist/types/plan-parser.d.ts +0 -38
- package/dist/types/plan-paths.d.ts +0 -36
- package/dist/types/port-forward-client.d.ts +0 -8
- package/dist/types/project-checkout-garbage.d.ts +0 -86
- package/dist/types/project-mirror-fetch-policy.d.ts +0 -84
- package/dist/types/project-mirror-refs-token.d.ts +0 -53
- package/dist/types/project-workspace-state.d.ts +0 -188
- package/dist/types/project-worktrees.d.ts +0 -397
- package/dist/types/pty-output-coalescer.d.ts +0 -20
- package/dist/types/recovery-journal-protocol.d.ts +0 -35
- package/dist/types/recovery-journal-runtime.d.ts +0 -12
- package/dist/types/recovery-journal-stall-fixture.d.ts +0 -1
- package/dist/types/recovery-journal-thread.d.ts +0 -1
- package/dist/types/recovery-journal.d.ts +0 -248
- package/dist/types/recovery-output-window.d.ts +0 -19
- package/dist/types/recovery-protocol.d.ts +0 -59
- package/dist/types/recovery-store.d.ts +0 -52
- package/dist/types/registry-auth.d.ts +0 -47
- package/dist/types/repository-transition-policy.d.ts +0 -26
- package/dist/types/runtime-version.d.ts +0 -1
- package/dist/types/session-file-mutations.d.ts +0 -22
- package/dist/types/supervisor-daemonized-fixture.d.ts +0 -1
- package/dist/types/supervisor-launcher-cleanup-fixture.d.ts +0 -1
- package/dist/types/supervisor-signal-fixture.d.ts +0 -1
- package/dist/types/supervisor.d.ts +0 -23
- package/dist/types/three-way-merge.d.ts +0 -77
- package/dist/types/working-tree-mirror.d.ts +0 -424
- package/dist/types/workspace-automatic-sync-policy.d.ts +0 -57
- package/dist/types/workspace-branch-incarnation-policy.d.ts +0 -14
- package/dist/types/workspace-command-sync-policy.d.ts +0 -57
- package/dist/types/workspace-command-targets.d.ts +0 -37
- package/dist/types/workspace-filesystem-executor-thread.d.ts +0 -1
- package/dist/types/workspace-filesystem-executor.d.ts +0 -123
- package/dist/types/workspace-filesystem-job-types.d.ts +0 -302
- package/dist/types/workspace-filesystem-jobs.d.ts +0 -7
- package/dist/types/workspace-git-sync.d.ts +0 -514
- package/dist/types/workspace-hydration-ledger.d.ts +0 -76
- package/dist/types/workspace-hydration-merge.d.ts +0 -103
- package/dist/types/workspace-hydration-recovery-state.d.ts +0 -10
- package/dist/types/workspace-incident-state.d.ts +0 -19
- package/dist/types/workspace-merge-projection.d.ts +0 -69
- package/dist/types/workspace-mount-boundary.d.ts +0 -10
- package/dist/types/workspace-mount-hold-fence.d.ts +0 -42
- package/dist/types/workspace-mutation-gate.d.ts +0 -42
- package/dist/types/workspace-path-move.d.ts +0 -21
- package/dist/types/workspace-preserve-only-policy.d.ts +0 -15
- package/dist/types/workspace-project-config-policy.d.ts +0 -48
- package/dist/types/workspace-projection-ledger.d.ts +0 -59
- package/dist/types/workspace-publication-evidence.d.ts +0 -17
- package/dist/types/workspace-sync-coalescer.d.ts +0 -28
- /package/dist/types/{credential-authority-lock-fixture.d.ts → runtime/releases/main.d.ts} +0 -0
package/dist/mjs/supervisor.mjs
DELETED
|
@@ -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
|
-
};
|