Make remote and log resource ownership explicit

This commit is contained in:
vorotamoroz committed 2026-10-29 14:56:06 +00:00
1 parent db95f420b9
commit 28bc6e87a1
17 files changed
+987 -71

No files matched your search

+3 -7
View File
@@ -1,3 +1,4 @@
import { createOwnedResource } from "octagonal-wheels/resource";
import type { RemoteDBSettings } from "@vrtmrz/livesync-commonlib/compat/common/types";
/**
@@ -13,13 +14,8 @@ export interface ResourceReplicator {
/** Create one idempotent asynchronous disposer for a private Replicator. */
export function createReplicatorDisposer(replicator: ResourceReplicator): () => Promise<void> {
let disposal: Promise<void> | undefined;
return () => {
if (disposal === undefined) {
disposal = Promise.resolve().then(() => replicator.closeReplication());
}
return disposal;
};
const resource = createOwnedResource(replicator, (owned) => Promise.resolve().then(() => owned.closeReplication()));
return () => Promise.resolve(resource.dispose());
}
/** Fence a finite resource from later edits to its source settings object. */
@@ -0,0 +1,42 @@
import { describe, expect, it, vi } from "vitest";
import { createReplicatorDisposer } from "./shared";
describe("Replicator disposal", () => {
it("defers closing, preserves the receiver, and retains one completion promise", async () => {
let finish!: () => void;
const closed = new Promise<void>((resolve) => {
finish = resolve;
});
const replicator = {
closeReplication: vi.fn(function (this: unknown) {
expect(this).toBe(replicator);
return closed;
}),
};
const dispose = createReplicatorDisposer(replicator);
const pending = dispose();
expect(replicator.closeReplication).not.toHaveBeenCalled();
expect(dispose()).toBe(pending);
await Promise.resolve();
expect(replicator.closeReplication).toHaveBeenCalledOnce();
finish();
await pending;
expect(dispose()).toBe(pending);
expect(replicator.closeReplication).toHaveBeenCalledOnce();
});
it("retains synchronous closing failures as one rejected promise", async () => {
const error = new Error("close");
const replicator = {
closeReplication: vi.fn(() => {
throw error;
}),
};
const dispose = createReplicatorDisposer(replicator);
const pending = dispose();
await expect(pending).rejects.toBe(error);
expect(dispose()).toBe(pending);
await expect(dispose()).rejects.toBe(error);
expect(replicator.closeReplication).toHaveBeenCalledOnce();
});
});