diff options
Diffstat (limited to 'packages/taler-wallet-core/src/common.ts')
-rw-r--r-- | packages/taler-wallet-core/src/common.ts | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/packages/taler-wallet-core/src/common.ts b/packages/taler-wallet-core/src/common.ts index 6d116c47e..edaba5ba4 100644 --- a/packages/taler-wallet-core/src/common.ts +++ b/packages/taler-wallet-core/src/common.ts @@ -21,6 +21,7 @@ import { AbsoluteTime, AmountJson, Amounts, + AsyncFlag, CoinRefreshRequest, CoinStatus, Duration, @@ -35,6 +36,7 @@ import { TalerProtocolTimestamp, TombstoneIdStr, TransactionIdStr, + WalletNotification, assertUnreachable, checkDbInvariant, checkLogicInvariant, @@ -769,3 +771,53 @@ export enum PendingTaskType { declare const __taskIdStr: unique symbol; export type TaskIdStr = string & { [__taskIdStr]: true }; + +/** + * Wait until the wallet is in a particular state. + * + * Two functions must be provided: + * 1. checkState, which checks if the wallet is in the + * desired state. + * 2. filterNotification, which checks whether a notification + * might have lead to a state change. + */ +export async function genericWaitForState( + wex: WalletExecutionContext, + args: { + checkState: () => Promise<boolean>; + filterNotification: (notif: WalletNotification) => boolean; + }, +): Promise<void> { + await wex.taskScheduler.ensureRunning(); + + // FIXME: Clean up using the new JS "using" / Symbol.dispose syntax. + const flag = new AsyncFlag(); + // Raise purchaseNotifFlag whenever we get a notification + // about our refresh. + const cancelNotif = wex.ws.addNotificationListener((notif) => { + if (args.filterNotification(notif)) { + flag.raise(); + } + }); + const unregisterOnCancelled = wex.cancellationToken.onCancelled(() => { + cancelNotif(); + flag.raise(); + }); + + try { + while (true) { + if (wex.cancellationToken.isCancelled) { + throw Error("cancelled"); + } + if (await args.checkState()) { + return; + } + // Wait for the next transition + await flag.wait(); + flag.reset(); + } + } catch (e) { + unregisterOnCancelled(); + cancelNotif(); + } +} |