From 419b86c2a64c33a3506c88d69fd47d284ec59b24 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Mon, 27 Nov 2023 15:13:07 -0500 Subject: [PATCH] Add status attribute to deferred --- packages/suspense/src/types.ts | 1 + .../suspense/src/utils/createDeferred.test.ts | 5 +++++ packages/suspense/src/utils/createDeferred.ts | 20 ++++++++++++++----- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/suspense/src/types.ts b/packages/suspense/src/types.ts index 1a8262f..9cd5be8 100644 --- a/packages/suspense/src/types.ts +++ b/packages/suspense/src/types.ts @@ -92,6 +92,7 @@ export interface Deferred { promise: Promise; reject(error: any): void; resolve(value?: Type): void; + status: StatusPending | StatusRejected | StatusResolved; } // Cache types diff --git a/packages/suspense/src/utils/createDeferred.test.ts b/packages/suspense/src/utils/createDeferred.test.ts index a9de0e5..40b020a 100644 --- a/packages/suspense/src/utils/createDeferred.test.ts +++ b/packages/suspense/src/utils/createDeferred.test.ts @@ -1,11 +1,14 @@ +import { STATUS_PENDING, STATUS_REJECTED, STATUS_RESOLVED } from ".."; import { createDeferred } from "./createDeferred"; describe("createDeferred", () => { it("should resolve with a value", async () => { const deferred = createDeferred(); + expect(deferred.status).toBe(STATUS_PENDING); setTimeout(() => { deferred.resolve("Resolved value"); + expect(deferred.status).toBe(STATUS_RESOLVED); }, 0); await expect(await deferred.promise).toBe("Resolved value"); @@ -13,8 +16,10 @@ describe("createDeferred", () => { it("should reject with a value", async () => { const deferred = createDeferred(); + expect(deferred.status).toBe(STATUS_PENDING); deferred.reject("Expected error"); + expect(deferred.status).toBe(STATUS_REJECTED); let caught = null; diff --git a/packages/suspense/src/utils/createDeferred.ts b/packages/suspense/src/utils/createDeferred.ts index 54864d3..1b28494 100644 --- a/packages/suspense/src/utils/createDeferred.ts +++ b/packages/suspense/src/utils/createDeferred.ts @@ -1,4 +1,10 @@ -import { Deferred, Status } from "../types"; +import { STATUS_PENDING, STATUS_REJECTED, STATUS_RESOLVED } from ".."; +import { + Deferred, + StatusPending, + StatusRejected, + StatusResolved, +} from "../types"; // A "thenable" is a subset of the Promise API. // We could use a Promise as thenable, but Promises have a downside: they use the microtask queue. @@ -6,7 +12,7 @@ import { Deferred, Status } from "../types"; // // A "deferred" is a "thenable" that has convenience resolve/reject methods. export function createDeferred(debugLabel?: string): Deferred { - let status: Status = "pending"; + let status: StatusPending | StatusRejected | StatusResolved = STATUS_PENDING; let rejectPromise: (error: Error) => void; let resolvePromise: (value: Type | PromiseLike) => void; @@ -20,7 +26,7 @@ export function createDeferred(debugLabel?: string): Deferred { }); function assertPending() { - if (status !== "pending") { + if (status !== STATUS_PENDING) { throw Error(`Deferred has already been ${status}`); } } @@ -34,7 +40,7 @@ export function createDeferred(debugLabel?: string): Deferred { reject(error: Error) { assertPending(); - status = "rejected"; + status = STATUS_REJECTED; rejectPromise(error); }, @@ -42,10 +48,14 @@ export function createDeferred(debugLabel?: string): Deferred { resolve(value: Type) { assertPending(); - status = "resolved"; + status = STATUS_RESOLVED; resolvePromise(value); }, + + get status() { + return status; + }, }; return deferred;