Merge current main for Setup URI dependency alignment

This commit is contained in:
vorotamoroz
2026-09-30 17:12:04 +00:00
19 changed files with 1207 additions and 28 deletions
+7 -3
View File
@@ -10,7 +10,7 @@ import {
import { scheduleTask } from "octagonal-wheels/concurrency/task";
import { fireAndForget, isDirty, throttle } from "@vrtmrz/livesync-commonlib/compat/common/utils";
import {
collectingChunks,
chunkFetchCounts,
pluginScanningCount,
hiddenFilesEventCount,
hiddenFilesProcessingCount,
@@ -36,7 +36,11 @@ import {
formatRemoteActivityStatusLabel,
getTrackedRequestCount,
} from "./RemoteActivityStatus.ts";
import { createMinimumVisibleActivityCount, createPaddedCounterLabel } from "./StatusBarDisplay.ts";
import {
createChunkFetchCounterLabel,
createMinimumVisibleActivityCount,
createPaddedCounterLabel,
} from "./StatusBarDisplay.ts";
import type { LiveSyncCore } from "@/main.ts";
import { LiveSyncError } from "@vrtmrz/livesync-commonlib/compat/common/LSError";
import { isValidPath } from "@/common/utils.ts";
@@ -140,7 +144,7 @@ export class ModuleLog extends AbstractObsidianModule {
const labelStorageCount = registerDisplay(
createPaddedCounterLabel(this.services.replication.storageApplyingCount, `💾`)
);
const labelChunkCount = registerDisplay(createPaddedCounterLabel(collectingChunks, `🧩`));
const labelChunkCount = registerDisplay(createChunkFetchCounterLabel(chunkFetchCounts));
const labelPluginScanCount = registerDisplay(createPaddedCounterLabel(pluginScanningCount, `🔌`));
const labelConflictProcessCount = registerDisplay(
createPaddedCounterLabel(this.services.conflict.conflictProcessQueueCount, `🔩`)
+47
View File
@@ -131,3 +131,50 @@ export function createPaddedCounterLabel(
source.offChanged(update);
});
}
/**
* Displays the disjoint initial and retry chunk-fetch counts with the same
* padding and inactive linger behaviour as the other status counters.
*/
export function createChunkFetchCounterLabel(
source: ReactiveValue<{ initial: number; retrying: number }>
): DisposableReactiveValue<string> {
const initialCount = reactiveSource(0);
const retryingCount = reactiveSource(0);
const initialLabel = createPaddedCounterLabel(initialCount, "🛄");
const retryingLabel = createPaddedCounterLabel(retryingCount, "🔁");
const formatted = reactiveSource(`${initialLabel.value}${retryingLabel.value}`);
let updatingCounts = false;
let disposed = false;
const updateLabel = () => {
if (updatingCounts || disposed) return;
formatted.value = `${initialLabel.value}${retryingLabel.value}`;
};
initialLabel.onChanged(updateLabel);
retryingLabel.onChanged(updateLabel);
const updateCounts = () => {
if (disposed) return;
updatingCounts = true;
try {
initialCount.value = source.value.initial;
retryingCount.value = source.value.retrying;
} finally {
updatingCounts = false;
updateLabel();
}
};
source.onChanged(updateCounts);
updateCounts();
return asDisposableReactiveValue(formatted, () => {
if (disposed) return;
disposed = true;
source.offChanged(updateCounts);
initialLabel.offChanged(updateLabel);
retryingLabel.offChanged(updateLabel);
initialLabel.dispose();
retryingLabel.dispose();
});
}
@@ -3,6 +3,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
STATUS_COUNTER_INACTIVE_LINGER_MS,
createChunkFetchCounterLabel,
createMinimumVisibleActivityCount,
createPaddedCounterLabel,
} from "./StatusBarDisplay.ts";
@@ -137,3 +138,41 @@ describe("createPaddedCounterLabel", () => {
expect(display.value).toBe(" 📄\u20070");
});
});
describe("createChunkFetchCounterLabel", () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
it("keeps initial and retry counts separate across an unchanged-total handoff", () => {
const counts = reactiveSource({ initial: 2, retrying: 5 });
const display = createChunkFetchCounterLabel(counts);
const withoutPadding = () => display.value.replace(/\u2007/g, "");
const transitionSnapshots: string[] = [];
const observeTransitions = () => transitionSnapshots.push(withoutPadding());
expect(withoutPadding()).toBe(" 🛄2 🔁5");
display.onChanged(observeTransitions);
counts.value = { initial: 0, retrying: 7 };
expect(withoutPadding()).toBe(" 🛄0 🔁7");
expect(transitionSnapshots).toEqual([" 🛄0 🔁7"]);
display.offChanged(observeTransitions);
vi.advanceTimersByTime(STATUS_COUNTER_INACTIVE_LINGER_MS - 1);
expect(withoutPadding()).toBe(" 🛄0 🔁7");
vi.advanceTimersByTime(1);
expect(withoutPadding()).toBe(" 🔁7");
counts.value = { initial: 0, retrying: 0 };
expect(withoutPadding()).toBe(" 🔁0");
display.dispose();
vi.advanceTimersByTime(STATUS_COUNTER_INACTIVE_LINGER_MS);
counts.value = { initial: 1, retrying: 0 };
expect(withoutPadding()).toBe(" 🔁0");
});
});