@ricsam/r5d-worker 0.0.44 → 0.0.46
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/dist/cjs/main.cjs +361 -144
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/workspace-sync.cjs +187 -49
- package/dist/mjs/main.mjs +361 -144
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/workspace-sync.mjs +187 -49
- package/dist/types/main.d.ts +19 -8
- package/dist/types/workspace-sync.d.ts +3 -0
- package/package.json +1 -1
package/dist/cjs/package.json
CHANGED
|
@@ -53,6 +53,9 @@ const MAX_REPORTED_WORKSPACE_PATHS = 2e3;
|
|
|
53
53
|
const MAX_REPORTED_WORKSPACE_STATUS_BYTES = 256 * 1024;
|
|
54
54
|
const MAX_MIRROR_COMPARISON_CACHE_ENTRIES = 2e5;
|
|
55
55
|
const MIRROR_COMPARE_BUFFER_BYTES = 64 * 1024;
|
|
56
|
+
const DESTRUCTIVE_CHECKOUT_MIN_TRACKED_FILES = 20;
|
|
57
|
+
const DESTRUCTIVE_CHECKOUT_REMOVAL_RATIO = 0.8;
|
|
58
|
+
const ACTIVE_GIT_LOCK_PATHS = ["index.lock", "HEAD.lock", "packed-refs.lock", "shallow.lock"];
|
|
56
59
|
const mirrorComparisonCache = /* @__PURE__ */ new Map();
|
|
57
60
|
function gitArgs(input, args) {
|
|
58
61
|
return input.authHeader ? ["git", "-c", `http.extraHeader=${input.authHeader}`, ...args] : ["git", ...args];
|
|
@@ -128,6 +131,36 @@ function listGitEligibleFiles(checkoutPath) {
|
|
|
128
131
|
}
|
|
129
132
|
}).sort();
|
|
130
133
|
}
|
|
134
|
+
function checkoutGitSnapshot(checkoutPath) {
|
|
135
|
+
const gitPaths = Bun.spawnSync(
|
|
136
|
+
["git", "rev-parse", "--git-path", "index", ...ACTIVE_GIT_LOCK_PATHS.flatMap((lock) => ["--git-path", lock])],
|
|
137
|
+
{
|
|
138
|
+
cwd: checkoutPath,
|
|
139
|
+
stdout: "pipe",
|
|
140
|
+
stderr: "ignore",
|
|
141
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
if (gitPaths.exitCode !== 0) return null;
|
|
145
|
+
const [indexPath, ...lockPaths] = gitPaths.stdout.toString().trim().split(/\r?\n/).map((gitPath) => import_node_path.default.resolve(checkoutPath, gitPath));
|
|
146
|
+
if (!indexPath || lockPaths.length !== ACTIVE_GIT_LOCK_PATHS.length || lockPaths.some((lockPath) => import_node_fs.default.existsSync(lockPath))) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
const head = Bun.spawnSync(["git", "rev-parse", "--verify", "HEAD"], {
|
|
150
|
+
cwd: checkoutPath,
|
|
151
|
+
stdout: "pipe",
|
|
152
|
+
stderr: "ignore",
|
|
153
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
154
|
+
});
|
|
155
|
+
let indexSignature = "missing";
|
|
156
|
+
try {
|
|
157
|
+
const stat = import_node_fs.default.statSync(indexPath);
|
|
158
|
+
indexSignature = entrySignature(stat);
|
|
159
|
+
} catch {
|
|
160
|
+
}
|
|
161
|
+
if (lockPaths.some((lockPath) => import_node_fs.default.existsSync(lockPath))) return null;
|
|
162
|
+
return `${head.exitCode === 0 ? head.stdout.toString().trim() : "unborn"}\0${indexSignature}`;
|
|
163
|
+
}
|
|
131
164
|
function listShadowTrackedFiles(input, relativeRoot) {
|
|
132
165
|
const normalizedRoot = relativeRoot.split(import_node_path.default.sep).join("/").replace(/^\/+|\/+$/g, "");
|
|
133
166
|
const output = runGit(input, input.shadowRoot, ["ls-files", "-z", "--cached", "--", normalizedRoot], "list canonical workspace files");
|
|
@@ -257,11 +290,28 @@ function mirrorFileSet(sourceRoot, targetRoot, sourceFiles, targetFiles) {
|
|
|
257
290
|
}
|
|
258
291
|
removeEmptyDirectories(targetRoot);
|
|
259
292
|
}
|
|
293
|
+
function restoreShadowProjectSnapshot(input, relativeRoot) {
|
|
294
|
+
const shadowRoot = import_node_path.default.join(input.shadowRoot, ...relativeRoot.split("/"));
|
|
295
|
+
const headFiles = runGitResult(input, input.shadowRoot, ["ls-tree", "-r", "--name-only", "-z", "HEAD", "--", relativeRoot]);
|
|
296
|
+
if (headFiles.exitCode === 0 && headFiles.stdout) {
|
|
297
|
+
runGit(input, input.shadowRoot, ["restore", "--source=HEAD", "--worktree", "--", relativeRoot], "restore deferred checkout scan");
|
|
298
|
+
runGit(input, input.shadowRoot, ["clean", "-fd", "--", relativeRoot], "clean deferred checkout scan");
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
import_node_fs.default.rmSync(shadowRoot, { recursive: true, force: true });
|
|
302
|
+
}
|
|
260
303
|
function mirrorVisibleProjectToShadow(input, manifest, branchName) {
|
|
261
304
|
const visibleRoot = visibleProjectBranchPath(input.projectsRoot, manifest, branchName);
|
|
262
305
|
if (!import_node_fs.default.existsSync(import_node_path.default.join(visibleRoot, ".git"))) return;
|
|
263
|
-
const
|
|
264
|
-
|
|
306
|
+
const beforeSnapshot = checkoutGitSnapshot(visibleRoot);
|
|
307
|
+
if (!beforeSnapshot) return;
|
|
308
|
+
const visibleFiles = listGitEligibleFiles(visibleRoot);
|
|
309
|
+
const relativeRoot = workspaceProjectBranchRelativePath(manifest.projectId, branchName);
|
|
310
|
+
const shadowRoot = import_node_path.default.join(input.shadowRoot, ...relativeRoot.split("/"));
|
|
311
|
+
mirrorFileSet(visibleRoot, shadowRoot, visibleFiles, listFilesRecursively(shadowRoot));
|
|
312
|
+
if (checkoutGitSnapshot(visibleRoot) !== beforeSnapshot) {
|
|
313
|
+
restoreShadowProjectSnapshot(input, relativeRoot);
|
|
314
|
+
}
|
|
265
315
|
}
|
|
266
316
|
function mirrorShadowProjectToVisible(input, manifest, branchName) {
|
|
267
317
|
const visibleRoot = visibleProjectBranchPath(input.projectsRoot, manifest, branchName);
|
|
@@ -290,29 +340,7 @@ function mirrorShadowPlansToLocal(input, manifest, branchName) {
|
|
|
290
340
|
listFilesRecursively(targetRoot, planFilter)
|
|
291
341
|
);
|
|
292
342
|
}
|
|
293
|
-
function pruneDirectoryChildren(root, allowedNames) {
|
|
294
|
-
if (!import_node_fs.default.existsSync(root)) return;
|
|
295
|
-
for (const entry of import_node_fs.default.readdirSync(root)) {
|
|
296
|
-
if (allowedNames.has(entry)) continue;
|
|
297
|
-
const target = import_node_path.default.resolve(root, entry);
|
|
298
|
-
assertInside(root, target, "Workspace manifest prune path");
|
|
299
|
-
import_node_fs.default.rmSync(target, { recursive: true, force: true });
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
function pruneShadowToManifest(input) {
|
|
303
|
-
const projectIds = new Set(input.projects.map((project) => project.projectId));
|
|
304
|
-
const projectsRoot = import_node_path.default.join(input.shadowRoot, "projects");
|
|
305
|
-
const plansRoot = import_node_path.default.join(input.shadowRoot, "plans");
|
|
306
|
-
pruneDirectoryChildren(projectsRoot, projectIds);
|
|
307
|
-
pruneDirectoryChildren(plansRoot, projectIds);
|
|
308
|
-
for (const manifest of input.projects) {
|
|
309
|
-
const encodedBranches = new Set(manifest.branches.map(encodeWorkspaceBranch));
|
|
310
|
-
pruneDirectoryChildren(import_node_path.default.join(projectsRoot, manifest.projectId, "branches"), encodedBranches);
|
|
311
|
-
pruneDirectoryChildren(import_node_path.default.join(plansRoot, manifest.projectId), encodedBranches);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
343
|
function mirrorVisibleWorkspaceToShadow(input, excludedCheckouts = /* @__PURE__ */ new Set()) {
|
|
315
|
-
pruneShadowToManifest(input);
|
|
316
344
|
for (const manifest of [...input.projects].sort((left, right) => left.projectId.localeCompare(right.projectId))) {
|
|
317
345
|
for (const branchName of [...new Set(manifest.branches)].sort()) {
|
|
318
346
|
if (excludedCheckouts.has(`${manifest.projectId}\0${branchName}`)) continue;
|
|
@@ -326,13 +354,13 @@ function reconcileNewVisibleCheckouts(input) {
|
|
|
326
354
|
const manifest = input.projects.find((project) => project.projectId === target.projectId);
|
|
327
355
|
if (!manifest || !manifest.branches.includes(target.branchName)) continue;
|
|
328
356
|
const projectRoot = workspaceProjectBranchRelativePath(target.projectId, target.branchName);
|
|
329
|
-
if (listShadowTrackedFiles(input, projectRoot).length > 0) {
|
|
357
|
+
if (listShadowTrackedFiles(input, projectRoot).length > 0 || restoreShadowRootFromRemote(input, projectRoot)) {
|
|
330
358
|
mirrorShadowProjectToVisible(input, manifest, target.branchName);
|
|
331
359
|
} else {
|
|
332
360
|
mirrorVisibleProjectToShadow(input, manifest, target.branchName);
|
|
333
361
|
}
|
|
334
362
|
const plansRoot = workspacePlansRelativePath(target.projectId, target.branchName);
|
|
335
|
-
if (listShadowTrackedFiles(input, plansRoot).length > 0) {
|
|
363
|
+
if (listShadowTrackedFiles(input, plansRoot).length > 0 || restoreShadowRootFromRemote(input, plansRoot)) {
|
|
336
364
|
mirrorShadowPlansToLocal(input, manifest, target.branchName);
|
|
337
365
|
} else {
|
|
338
366
|
mirrorLocalPlansToShadow(input, manifest, target.branchName);
|
|
@@ -379,11 +407,103 @@ function revParse(input, revision) {
|
|
|
379
407
|
function gitStatus(input) {
|
|
380
408
|
return runGit(input, input.shadowRoot, ["status", "--porcelain=v1", "--untracked-files=all"], "read workspace status");
|
|
381
409
|
}
|
|
382
|
-
function
|
|
383
|
-
|
|
410
|
+
function resetUncommittedShadowSnapshot(input) {
|
|
411
|
+
if (!gitStatus(input)) return;
|
|
412
|
+
if (tryGit(input, input.shadowRoot, ["rev-parse", "--verify", "HEAD"])) {
|
|
413
|
+
runGit(input, input.shadowRoot, ["reset", "--hard", "HEAD"], "reset interrupted workspace snapshot");
|
|
414
|
+
} else {
|
|
415
|
+
runGit(input, input.shadowRoot, ["read-tree", "--empty"], "reset interrupted unborn workspace snapshot");
|
|
416
|
+
}
|
|
417
|
+
runGit(input, input.shadowRoot, ["clean", "-fd"], "clean interrupted workspace snapshot");
|
|
418
|
+
}
|
|
419
|
+
function fastForwardCleanShadowForNewCheckouts(input) {
|
|
420
|
+
if (!input.newVisibleCheckouts?.length) return;
|
|
421
|
+
runGit(input, input.shadowRoot, ["add", "-A"], "stage existing workspace changes before checkout hydration");
|
|
422
|
+
if (gitStatus(input)) return;
|
|
423
|
+
const localHead = revParse(input, "HEAD");
|
|
424
|
+
const remoteHead = revParse(input, `origin/${WORKSPACE_BRANCH}`);
|
|
425
|
+
if (!localHead || !remoteHead || localHead === remoteHead) return;
|
|
426
|
+
if (!tryGit(input, input.shadowRoot, ["merge-base", "--is-ancestor", localHead, remoteHead])) return;
|
|
427
|
+
runGit(input, input.shadowRoot, ["reset", "--hard", remoteHead], "fast-forward before checkout hydration");
|
|
428
|
+
}
|
|
429
|
+
function restoreShadowRootFromRemote(input, relativeRoot) {
|
|
430
|
+
const remoteRevision = `origin/${WORKSPACE_BRANCH}`;
|
|
431
|
+
const remoteFiles = runGitResult(input, input.shadowRoot, ["ls-tree", "-r", "--name-only", "-z", remoteRevision, "--", relativeRoot]);
|
|
432
|
+
if (remoteFiles.exitCode !== 0 || !remoteFiles.stdout) return false;
|
|
433
|
+
runGit(
|
|
434
|
+
input,
|
|
435
|
+
input.shadowRoot,
|
|
436
|
+
["restore", `--source=${remoteRevision}`, "--staged", "--worktree", "--", relativeRoot],
|
|
437
|
+
`hydrate ${relativeRoot} from canonical workspace`
|
|
438
|
+
);
|
|
439
|
+
return true;
|
|
384
440
|
}
|
|
385
|
-
|
|
386
|
-
const
|
|
441
|
+
function candidateBaseRevision(input) {
|
|
442
|
+
const localHead = revParse(input, "HEAD");
|
|
443
|
+
if (!localHead) return null;
|
|
444
|
+
const remoteHead = revParse(input, `origin/${WORKSPACE_BRANCH}`);
|
|
445
|
+
if (!remoteHead) {
|
|
446
|
+
const emptyTree = Bun.spawnSync(gitArgs(input, ["mktree"]), {
|
|
447
|
+
cwd: input.shadowRoot,
|
|
448
|
+
stdin: Buffer.alloc(0),
|
|
449
|
+
stdout: "pipe",
|
|
450
|
+
stderr: "pipe",
|
|
451
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" }
|
|
452
|
+
});
|
|
453
|
+
if (emptyTree.exitCode !== 0) {
|
|
454
|
+
throw new Error(
|
|
455
|
+
`create empty workspace comparison tree: ${emptyTree.stderr.toString().trim() || `git exited ${emptyTree.exitCode}`}`
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
return emptyTree.stdout.toString().trim();
|
|
459
|
+
}
|
|
460
|
+
const mergeBase = runGitResult(input, input.shadowRoot, ["merge-base", localHead, remoteHead]);
|
|
461
|
+
return mergeBase.exitCode === 0 && mergeBase.stdout ? mergeBase.stdout : remoteHead;
|
|
462
|
+
}
|
|
463
|
+
function stagedPaths(input, baseRevision) {
|
|
464
|
+
return runGit(
|
|
465
|
+
input,
|
|
466
|
+
input.shadowRoot,
|
|
467
|
+
["diff", "--cached", "--name-only", "-z", ...baseRevision ? [baseRevision] : []],
|
|
468
|
+
"list workspace changes"
|
|
469
|
+
).split("\0").filter(Boolean).sort();
|
|
470
|
+
}
|
|
471
|
+
function stagedDeletedPaths(input, baseRevision) {
|
|
472
|
+
return runGit(
|
|
473
|
+
input,
|
|
474
|
+
input.shadowRoot,
|
|
475
|
+
["diff", "--cached", "--diff-filter=D", "--name-only", "-z", ...baseRevision ? [baseRevision] : []],
|
|
476
|
+
"list workspace deletions"
|
|
477
|
+
).split("\0").filter(Boolean).sort();
|
|
478
|
+
}
|
|
479
|
+
function managedCheckoutRoot(filePath) {
|
|
480
|
+
const projectMatch = /^projects\/([^/]+)\/branches\/([^/]+)\//.exec(filePath);
|
|
481
|
+
return projectMatch ? `projects/${projectMatch[1]}/branches/${projectMatch[2]}` : null;
|
|
482
|
+
}
|
|
483
|
+
function revisionTrackedFileCount(input, revision, relativeRoot) {
|
|
484
|
+
if (!revision) return 0;
|
|
485
|
+
const result = runGitResult(input, input.shadowRoot, ["ls-tree", "-r", "--name-only", "-z", revision, "--", relativeRoot]);
|
|
486
|
+
if (result.exitCode !== 0) return 0;
|
|
487
|
+
return result.stdout.split("\0").filter(Boolean).length;
|
|
488
|
+
}
|
|
489
|
+
function destructiveCheckoutReductions(input, baseRevision) {
|
|
490
|
+
const roots = new Set(
|
|
491
|
+
stagedDeletedPaths(input, baseRevision).map(managedCheckoutRoot).filter((root) => Boolean(root))
|
|
492
|
+
);
|
|
493
|
+
const destructive = [];
|
|
494
|
+
for (const root of roots) {
|
|
495
|
+
const trackedBefore = revisionTrackedFileCount(input, baseRevision, root);
|
|
496
|
+
if (trackedBefore === 0) continue;
|
|
497
|
+
const trackedAfter = listShadowTrackedFiles(input, root).length;
|
|
498
|
+
const removedRatio = (trackedBefore - trackedAfter) / trackedBefore;
|
|
499
|
+
if (trackedAfter === 0 || trackedBefore >= DESTRUCTIVE_CHECKOUT_MIN_TRACKED_FILES && removedRatio >= DESTRUCTIVE_CHECKOUT_REMOVAL_RATIO) {
|
|
500
|
+
destructive.push({ root, trackedBefore, trackedAfter });
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return destructive.sort((left, right) => left.root.localeCompare(right.root));
|
|
504
|
+
}
|
|
505
|
+
async function stagedDiffSizeBytes(input, baseRevision) {
|
|
506
|
+
const subprocess = Bun.spawn(gitArgs(input, ["diff", "--cached", "--binary", "--no-ext-diff", ...baseRevision ? [baseRevision] : []]), {
|
|
387
507
|
cwd: input.shadowRoot,
|
|
388
508
|
stdout: "pipe",
|
|
389
509
|
stderr: "pipe",
|
|
@@ -486,13 +606,17 @@ async function synchronizeWorkspace(rawInput) {
|
|
|
486
606
|
};
|
|
487
607
|
}
|
|
488
608
|
if (!input.skipVisibleMirror) {
|
|
609
|
+
resetUncommittedShadowSnapshot(input);
|
|
489
610
|
const newCheckoutKeys = new Set((input.newVisibleCheckouts ?? []).map((target) => `${target.projectId}\0${target.branchName}`));
|
|
490
611
|
mirrorVisibleWorkspaceToShadow(input, newCheckoutKeys);
|
|
612
|
+
fastForwardCleanShadowForNewCheckouts(input);
|
|
491
613
|
reconcileNewVisibleCheckouts(input);
|
|
492
614
|
}
|
|
493
615
|
runGit(input, input.shadowRoot, ["add", "-A"], "stage workspace changes");
|
|
494
|
-
const
|
|
495
|
-
const
|
|
616
|
+
const stagedWorkingPaths = stagedPaths(input);
|
|
617
|
+
const baseRevision = candidateBaseRevision(input);
|
|
618
|
+
const paths = stagedPaths(input, baseRevision);
|
|
619
|
+
const diffSizeBytes = await stagedDiffSizeBytes(input, baseRevision);
|
|
496
620
|
const statusBeforeCommit = reportedStatus(gitStatus(input));
|
|
497
621
|
const observed = {
|
|
498
622
|
...result,
|
|
@@ -501,10 +625,23 @@ async function synchronizeWorkspace(rawInput) {
|
|
|
501
625
|
affectedPaths: reportedPaths(paths),
|
|
502
626
|
affectedProjects: affectedProjects(paths)
|
|
503
627
|
};
|
|
628
|
+
const destructiveReductions = destructiveCheckoutReductions(input, baseRevision);
|
|
629
|
+
if (destructiveReductions.length > 0 && !input.confirmedLargeDiff) {
|
|
630
|
+
const summary = destructiveReductions.map(({ root, trackedBefore, trackedAfter }) => `${root} (${trackedBefore} -> ${trackedAfter} tracked files)`).join(", ");
|
|
631
|
+
return {
|
|
632
|
+
...observed,
|
|
633
|
+
outcome: "large_diff_blocked",
|
|
634
|
+
error: `Workspace safety guard blocked a destructive checkout reduction: ${summary}`
|
|
635
|
+
};
|
|
636
|
+
}
|
|
504
637
|
if (paths.length > 0 && diffSizeBytes > MAX_WORKSPACE_SYNC_DIFF_BYTES && !input.confirmedLargeDiff) {
|
|
505
|
-
return {
|
|
638
|
+
return {
|
|
639
|
+
...observed,
|
|
640
|
+
outcome: "large_diff_blocked",
|
|
641
|
+
error: `Workspace safety guard blocked a ${diffSizeBytes}-byte diff above the ${MAX_WORKSPACE_SYNC_DIFF_BYTES}-byte automatic publication limit.`
|
|
642
|
+
};
|
|
506
643
|
}
|
|
507
|
-
if (
|
|
644
|
+
if (stagedWorkingPaths.length > 0) {
|
|
508
645
|
runGit(input, input.shadowRoot, ["commit", "-m", commitMessage(input)], "commit workspace changes");
|
|
509
646
|
}
|
|
510
647
|
const candidateHead = revParse(input, "HEAD");
|
|
@@ -597,7 +734,10 @@ async function synchronizeWorkspace(rawInput) {
|
|
|
597
734
|
}
|
|
598
735
|
function calculateWorkspaceDiffFingerprint(input) {
|
|
599
736
|
ensureShadowWorkspace(input);
|
|
600
|
-
if (!input.skipVisibleMirror)
|
|
737
|
+
if (!input.skipVisibleMirror) {
|
|
738
|
+
resetUncommittedShadowSnapshot(input);
|
|
739
|
+
mirrorVisibleWorkspaceToShadow(input);
|
|
740
|
+
}
|
|
601
741
|
runGit(input, input.shadowRoot, ["add", "-A"], "stage workspace fingerprint");
|
|
602
742
|
const stagedTree = runGit(input, input.shadowRoot, ["write-tree"], "write workspace fingerprint tree");
|
|
603
743
|
const headTree = revParse(input, "HEAD^{tree}");
|
|
@@ -610,27 +750,25 @@ function calculateWorkspaceDiffFingerprint(input) {
|
|
|
610
750
|
}
|
|
611
751
|
class WorkspaceSyncSingleFlight {
|
|
612
752
|
queue = Promise.resolve();
|
|
613
|
-
|
|
614
|
-
const queued = this.queue.then(
|
|
615
|
-
() => synchronizeWorkspace(input),
|
|
616
|
-
() => synchronizeWorkspace(input)
|
|
617
|
-
);
|
|
753
|
+
enqueue(task) {
|
|
754
|
+
const queued = this.queue.then(task, task);
|
|
618
755
|
this.queue = queued.then(
|
|
619
756
|
() => void 0,
|
|
620
757
|
() => void 0
|
|
621
758
|
);
|
|
622
759
|
return queued;
|
|
623
760
|
}
|
|
761
|
+
run(input) {
|
|
762
|
+
return this.enqueue(() => synchronizeWorkspace(input));
|
|
763
|
+
}
|
|
764
|
+
runPrepared(prepare) {
|
|
765
|
+
return this.enqueue(() => synchronizeWorkspace(prepare()));
|
|
766
|
+
}
|
|
624
767
|
fingerprint(input) {
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
);
|
|
629
|
-
this.queue = queued.then(
|
|
630
|
-
() => void 0,
|
|
631
|
-
() => void 0
|
|
632
|
-
);
|
|
633
|
-
return queued;
|
|
768
|
+
return this.enqueue(() => calculateWorkspaceDiffFingerprint(input));
|
|
769
|
+
}
|
|
770
|
+
fingerprintPrepared(prepare) {
|
|
771
|
+
return this.enqueue(() => calculateWorkspaceDiffFingerprint(prepare()));
|
|
634
772
|
}
|
|
635
773
|
afterCurrent() {
|
|
636
774
|
return this.queue;
|