mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-11-05 07:48:18 +00:00
Make remote and log resource ownership explicit
This commit is contained in:
1 parent
db95f420b9
commit
28bc6e87a1
17 files changed
+987
-71
No files matched your search
@@ -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();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user