mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(chord): allow promise probes on settled drafts
This commit is contained in:
parent
d5629e2048
commit
6966636dbe
2 changed files with 40 additions and 5 deletions
|
|
@ -388,6 +388,10 @@ const sharedObjectHandler: ProxyHandler<object> = {
|
|||
throw new TypeError("Defining overlay properties is not supported");
|
||||
},
|
||||
get(target, property) {
|
||||
if (property === "then") {
|
||||
const node = (target as Record<PropertyKey, unknown>)[NODE] as OverlayNode | undefined;
|
||||
if (node === undefined || isSettledContext(node.context)) return undefined;
|
||||
}
|
||||
const node = nodeForTarget(target);
|
||||
if (property === NODE) return node;
|
||||
return getProperty(node, property);
|
||||
|
|
@ -499,15 +503,17 @@ function nodeForTarget(target: object): OverlayNode {
|
|||
return node;
|
||||
}
|
||||
|
||||
function assertReadable(context: OverlayContext): void {
|
||||
if (
|
||||
function isSettledContext(context: OverlayContext): boolean {
|
||||
return (
|
||||
context.overlayReleased ||
|
||||
context.status.value === "consumed" ||
|
||||
context.status.value === "aborted" ||
|
||||
context.status.value === "stale"
|
||||
) {
|
||||
throw new TypeError("Cannot use a settled overlay");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function assertReadable(context: OverlayContext): void {
|
||||
if (isSettledContext(context)) throw new TypeError("Cannot use a settled overlay");
|
||||
}
|
||||
|
||||
function assertWritable(context: OverlayContext): void {
|
||||
|
|
|
|||
|
|
@ -86,6 +86,35 @@ describe("delta tracker transactional overlay lifecycle", () => {
|
|||
tracker.adopt(prepared);
|
||||
});
|
||||
|
||||
it("allows Promise resolution to inspect a settled draft without reporting a false failure", async () => {
|
||||
const initial = JSON.parse('{"then":"document-value","value":1}') as { then: string; value: number };
|
||||
const tracker = track(initial);
|
||||
const change = tracker.beginChange();
|
||||
const draft = change.state;
|
||||
expect(draft.then).toBe("document-value");
|
||||
draft.value = 2;
|
||||
const prepared = change.prepare();
|
||||
|
||||
const resolved = await Promise.resolve(draft);
|
||||
expect(resolved).toBe(draft);
|
||||
expect(resolved.then).toBeUndefined();
|
||||
expect(() => resolved.value).toThrow(/settled/);
|
||||
|
||||
tracker.adopt(prepared);
|
||||
expect(tracker.value.then).toBe("document-value");
|
||||
expect(tracker.value.value).toBe(2);
|
||||
|
||||
const largeTracker = track({ rows: Array.from({ length: 4_100 }, (_, value) => ({ value })) });
|
||||
const largeChange = largeTracker.beginChange();
|
||||
const largeDraft = largeChange.state;
|
||||
for (const row of largeDraft.rows) expect(row.value).toBeGreaterThanOrEqual(0);
|
||||
largeDraft.rows[0]!.value = -1;
|
||||
const largePrepared = largeChange.prepare();
|
||||
expect(await Promise.resolve(largeDraft)).toBe(largeDraft);
|
||||
expect(() => largeDraft.rows).toThrow(/settled/);
|
||||
largeTracker.adopt(largePrepared);
|
||||
});
|
||||
|
||||
it("aborts idempotently and revokes held descendants", () => {
|
||||
const tracker = track({ child: { value: 1 } });
|
||||
const change = tracker.beginChange();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue