refactor: switch to using defer's

This commit is contained in:
Derrick Hammer 2023-09-10 18:46:23 -04:00
parent 665117dfac
commit c4e211b04c
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
2 changed files with 36 additions and 46 deletions

View File

@ -1,9 +1,9 @@
import { import {
init, init,
kernelAuthLocation, kernelAuthLocation,
kernelLoadedPromise, kernelLoadedDefer,
loginPromise, loginDefer,
logoutPromise, logoutDefer,
} from "./queries.js"; } from "./queries.js";
import { Err } from "#types.js"; import { Err } from "#types.js";
@ -33,7 +33,7 @@ import { Err } from "#types.js";
// loginComplete will resolve when the user has successfully logged in. // loginComplete will resolve when the user has successfully logged in.
function loginComplete(): Promise<void> { function loginComplete(): Promise<void> {
return loginPromise; return loginDefer.promise;
} }
// kernelLoaded will resolve when the user has successfully loaded the kernel. // kernelLoaded will resolve when the user has successfully loaded the kernel.
@ -41,14 +41,14 @@ function loginComplete(): Promise<void> {
// //
// NOTE: kernelLoaded will not resolve until after loginComplete has resolved. // NOTE: kernelLoaded will not resolve until after loginComplete has resolved.
function kernelLoaded(): Promise<Err> { function kernelLoaded(): Promise<Err> {
return kernelLoadedPromise; return kernelLoadedDefer.promise;
} }
// logoutComplete will resolve when the user has logged out. Note that // logoutComplete will resolve when the user has logged out. Note that
// logoutComplete will only resolve if the user logged in first - if the user // logoutComplete will only resolve if the user logged in first - if the user
// was not logged in to begin with, this promise will not resolve. // was not logged in to begin with, this promise will not resolve.
function logoutComplete(): Promise<void> { function logoutComplete(): Promise<void> {
return logoutPromise; return logoutDefer.promise;
} }
// openAuthWindow is intended to be used as an onclick target when the user // openAuthWindow is intended to be used as an onclick target when the user

View File

@ -1,6 +1,7 @@
import { log, logErr } from "./log.js"; import { log, logErr } from "./log.js";
import { DataFn, Err, ErrTuple } from "#types.js"; import { DataFn, Err, ErrTuple } from "#types.js";
import { bufToB64, encodeU64 } from "#util.js"; import { bufToB64, encodeU64 } from "#util.js";
import defer, { DeferredPromise } from "p-defer";
// queryResolve is the 'resolve' value of a promise that returns an ErrTuple. // queryResolve is the 'resolve' value of a promise that returns an ErrTuple.
// It gets called when a query sends a 'response' message. // It gets called when a query sends a 'response' message.
@ -154,15 +155,15 @@ function handleMessage(event: MessageEvent) {
// We can't actually establish that init is complete until the // We can't actually establish that init is complete until the
// kernel source has been set. This happens async and might happen // kernel source has been set. This happens async and might happen
// after we receive the auth message. // after we receive the auth message.
sourcePromise.then(() => { sourceDefer.promise.then(() => {
initResolve(); initDefer.resolve();
}); });
} }
if (IS_EXTENSION_ANY && event.data.data.kernelLoaded === "success") { if (IS_EXTENSION_ANY && event.data.data.kernelLoaded === "success") {
const nonce = nextNonce(); const nonce = nextNonce();
queries[nonce] = { queries[nonce] = {
resolve: sourceResolve, resolve: sourceDefer.resolve as unknown as queryResolve,
}; };
const kernelMessage = { const kernelMessage = {
@ -181,7 +182,7 @@ function handleMessage(event: MessageEvent) {
// that the user is logged in. // that the user is logged in.
if (!loginResolved && event.data.data.loginComplete) { if (!loginResolved && event.data.data.loginComplete) {
loginResolved = true; loginResolved = true;
loginResolve(); loginDefer.resolve();
} }
// If the auth status message says that the kernel loaded, it means // If the auth status message says that the kernel loaded, it means
@ -199,7 +200,7 @@ function handleMessage(event: MessageEvent) {
// out, we need to reload the page and reset the auth process. // out, we need to reload the page and reset the auth process.
if (event.data.data.logoutComplete) { if (event.data.data.logoutComplete) {
if (!logoutResolved) { if (!logoutResolved) {
logoutResolve(); logoutDefer.resolve();
} }
window.location.reload(); window.location.reload();
} }
@ -258,7 +259,7 @@ function launchKernelFrame() {
kernelSource = <Window>iframe.contentWindow; kernelSource = <Window>iframe.contentWindow;
kernelOrigin = EXTENSION_HOSTED_ORIGIN; kernelOrigin = EXTENSION_HOSTED_ORIGIN;
kernelAuthLocation = `${EXTENSION_HOSTED_ORIGIN}/auth.html`; kernelAuthLocation = `${EXTENSION_HOSTED_ORIGIN}/auth.html`;
sourceResolve(); sourceDefer.resolve();
// Set a timer to fail the login process if the kernel doesn't load in // Set a timer to fail the login process if the kernel doesn't load in
// time. // time.
@ -267,7 +268,9 @@ function launchKernelFrame() {
return; return;
} }
initResolved = true; initResolved = true;
initResolve("tried to open kernel in iframe, but hit a timeout"); initDefer.resolve(
"tried to open kernel in iframe, but hit a timeout" as any,
);
}, 24000); }, 24000);
} }
@ -318,7 +321,7 @@ function messageBridge() {
kernelAuthLocation = `${EXTENSION_KERNEL_ORIGIN}/auth.html`; kernelAuthLocation = `${EXTENSION_KERNEL_ORIGIN}/auth.html`;
log("established connection to bridge, using browser extension for kernel"); log("established connection to bridge, using browser extension for kernel");
if (!IS_EXTENSION_ANY) { if (!IS_EXTENSION_ANY) {
sourceResolve(); sourceDefer.resolve();
} }
}); });
@ -357,7 +360,7 @@ function messageBridge() {
bridgeResolve([null, null]); bridgeResolve([null, null]);
} }
return initPromise; return initDefer;
} }
// init is a function that returns a promise which will resolve when // init is a function that returns a promise which will resolve when
@ -368,23 +371,19 @@ function messageBridge() {
// thanks to the 'initialized' variable. // thanks to the 'initialized' variable.
let initialized = false; // set to true once 'init()' has been called let initialized = false; // set to true once 'init()' has been called
let initResolved = false; // set to true once we know the bootloader is working let initResolved = false; // set to true once we know the bootloader is working
let initResolve: DataFn; let initDefer: DeferredPromise<void>;
let initPromise: Promise<void>;
let loginResolved = false; // set to true once we know the user is logged in let loginResolved = false; // set to true once we know the user is logged in
let loginResolve: () => void; let loginDefer: DeferredPromise<void>;
let loginPromise: Promise<void>;
let kernelLoadedResolved = false; // set to true once the user kernel is loaded let kernelLoadedResolved = false; // set to true once the user kernel is loaded
let kernelLoadedResolve: (err: Err) => void; let kernelLoadedResolve: (err: Err) => void;
let kernelLoadedPromise: Promise<Err>; let kernelLoadedDefer: DeferredPromise<Err>;
const logoutResolved = false; // set to true once the user is logged out const logoutResolved = false; // set to true once the user is logged out
let logoutResolve: () => void; let logoutDefer: DeferredPromise<void>;
let logoutPromise: Promise<void>; let sourceDefer: DeferredPromise<void>; // resolves when the source is known and set
let sourceResolve: () => void;
let sourcePromise: Promise<void>; // resolves when the source is known and set
function init(): Promise<void> { function init(): Promise<void> {
// If init has already been called, just return the init promise. // If init has already been called, just return the init promise.
if (initialized) { if (initialized) {
return initPromise; return initDefer.promise;
} }
initialized = true; initialized = true;
@ -394,25 +393,16 @@ function init(): Promise<void> {
messageBridge(); messageBridge();
// Create the promises that resolve at various stages of the auth flow. // Create the promises that resolve at various stages of the auth flow.
initPromise = new Promise((resolve) => { initDefer = defer();
initResolve = resolve; loginDefer = defer();
}); kernelLoadedDefer = defer();
loginPromise = new Promise((resolve) => { logoutDefer = defer();
loginResolve = resolve; kernelLoadedDefer = defer();
}); sourceDefer = defer();
kernelLoadedPromise = new Promise((resolve) => {
kernelLoadedResolve = resolve;
});
logoutPromise = new Promise((resolve) => {
logoutResolve = resolve;
});
sourcePromise = new Promise((resolve) => {
sourceResolve = resolve;
});
// Return the initPromise, which will resolve when bootloader init is // Return the initDefer, which will resolve when bootloader init is
// complete. // complete.
return initPromise; return initDefer.promise;
} }
// callModule is a generic function to call a module. The first input is the // callModule is a generic function to call a module. The first input is the
@ -536,7 +526,7 @@ function newKernelQuery(
// implies that init is complete. // implies that init is complete.
const getNonce: Promise<string> = new Promise((resolve) => { const getNonce: Promise<string> = new Promise((resolve) => {
init().then(() => { init().then(() => {
kernelLoadedPromise.then(() => { kernelLoadedDefer.promise.then(() => {
resolve(nextNonce()); resolve(nextNonce());
}); });
}); });
@ -653,8 +643,8 @@ export {
connectModule, connectModule,
init, init,
kernelAuthLocation, kernelAuthLocation,
kernelLoadedPromise, kernelLoadedDefer,
loginPromise, loginDefer,
logoutPromise, logoutDefer,
newKernelQuery, newKernelQuery,
}; };