summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/util
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2024-01-09 16:23:26 +0100
committerFlorian Dold <florian@dold.me>2024-01-09 16:23:26 +0100
commitf8cde03f0cb6a7584fb92885f8979a01916a917d (patch)
tree6f120387f8f5297f436e2d2bd2d4d7b5c1814146 /packages/taler-wallet-core/src/util
parentde39d432374a3ecd1bddd788b1ac1585461af8c1 (diff)
downloadwallet-core-f8cde03f0cb6a7584fb92885f8979a01916a917d.tar.gz
wallet-core-f8cde03f0cb6a7584fb92885f8979a01916a917d.tar.bz2
wallet-core-f8cde03f0cb6a7584fb92885f8979a01916a917d.zip
wallet-core: refactor peer-pull-debit and test aborting
Diffstat (limited to 'packages/taler-wallet-core/src/util')
-rw-r--r--packages/taler-wallet-core/src/util/coinSelection.ts12
-rw-r--r--packages/taler-wallet-core/src/util/query.ts98
2 files changed, 99 insertions, 11 deletions
diff --git a/packages/taler-wallet-core/src/util/coinSelection.ts b/packages/taler-wallet-core/src/util/coinSelection.ts
index 6070f4c78..9b29cee26 100644
--- a/packages/taler-wallet-core/src/util/coinSelection.ts
+++ b/packages/taler-wallet-core/src/util/coinSelection.ts
@@ -233,9 +233,9 @@ function tallyFees(
export type SelectPayCoinsResult =
| {
- type: "failure";
- insufficientBalanceDetails: PayMerchantInsufficientBalanceDetails;
- }
+ type: "failure";
+ insufficientBalanceDetails: PayMerchantInsufficientBalanceDetails;
+ }
| { type: "success"; coinSel: PayCoinSelection };
/**
@@ -889,9 +889,9 @@ export interface PeerCoinSelectionDetails {
export type SelectPeerCoinsResult =
| { type: "success"; result: PeerCoinSelectionDetails }
| {
- type: "failure";
- insufficientBalanceDetails: PayPeerInsufficientBalanceDetails;
- };
+ type: "failure";
+ insufficientBalanceDetails: PayPeerInsufficientBalanceDetails;
+ };
export interface PeerCoinRepair {
exchangeBaseUrl: string;
diff --git a/packages/taler-wallet-core/src/util/query.ts b/packages/taler-wallet-core/src/util/query.ts
index 309c17a43..5d563f620 100644
--- a/packages/taler-wallet-core/src/util/query.ts
+++ b/packages/taler-wallet-core/src/util/query.ts
@@ -454,8 +454,8 @@ type DerefKeyPath<T, P> = P extends `${infer PX extends keyof T &
KeyPathComponents}`
? T[PX]
: P extends `${infer P0 extends keyof T & KeyPathComponents}.${infer Rest}`
- ? DerefKeyPath<T[P0], Rest>
- : unknown;
+ ? DerefKeyPath<T[P0], Rest>
+ : unknown;
/**
* Return a path if it is a valid dot-separate path to an object.
@@ -465,8 +465,8 @@ type ValidateKeyPath<T, P> = P extends `${infer PX extends keyof T &
KeyPathComponents}`
? PX
: P extends `${infer P0 extends keyof T & KeyPathComponents}.${infer Rest}`
- ? `${P0}.${ValidateKeyPath<T[P0], Rest>}`
- : never;
+ ? `${P0}.${ValidateKeyPath<T[P0], Rest>}`
+ : never;
// function foo<T, P>(
// x: T,
@@ -545,11 +545,60 @@ type ReadWriteTransactionFunction<BoundStores, T> = (
rawTx: IDBTransaction,
) => Promise<T>;
+export type DbReadWriteTransactionArr<
+ StoreMap,
+ StoresArr extends Array<StoreNames<StoreMap>>,
+> = StoreMap extends {
+ [P in string]: StoreWithIndexes<infer _SN1, infer _SD1, infer _IM1>;
+}
+ ? {
+ [X in StoresArr[number] &
+ keyof StoreMap]: StoreMap[X] extends StoreWithIndexes<
+ infer _StoreName,
+ infer RecordType,
+ infer IndexMap
+ >
+ ? StoreReadWriteAccessor<RecordType, IndexMap>
+ : unknown;
+ }
+ : never;
+
+export type DbReadOnlyTransactionArr<
+ StoreMap,
+ StoresArr extends Array<StoreNames<StoreMap>>,
+> = StoreMap extends {
+ [P in string]: StoreWithIndexes<infer _SN1, infer _SD1, infer _IM1>;
+}
+ ? {
+ [X in StoresArr[number] &
+ keyof StoreMap]: StoreMap[X] extends StoreWithIndexes<
+ infer _StoreName,
+ infer RecordType,
+ infer IndexMap
+ >
+ ? StoreReadOnlyAccessor<RecordType, IndexMap>
+ : unknown;
+ }
+ : never;
+
export interface TransactionContext<BoundStores> {
runReadWrite<T>(f: ReadWriteTransactionFunction<BoundStores, T>): Promise<T>;
runReadOnly<T>(f: ReadOnlyTransactionFunction<BoundStores, T>): Promise<T>;
}
+/**
+ * Convert the type of an array to a union of the contents.
+ *
+ * Example:
+ * Input ["foo", "bar"]
+ * Output "foo" | "bar"
+ */
+export type UnionFromArray<Arr> = Arr extends {
+ [X in keyof Arr]: Arr[X] & string;
+}
+ ? Arr[keyof Arr & number]
+ : unknown;
+
function runTx<Arg, Res>(
tx: IDBTransaction,
arg: Arg,
@@ -743,7 +792,10 @@ type StoreNamesOf<X> = X extends { [x: number]: infer F }
* A store map is the metadata that describes the store.
*/
export class DbAccess<StoreMap> {
- constructor(private db: IDBDatabase, private stores: StoreMap) {}
+ constructor(
+ private db: IDBDatabase,
+ private stores: StoreMap,
+ ) {}
idbHandle(): IDBDatabase {
return this.db;
@@ -803,6 +855,42 @@ export class DbAccess<StoreMap> {
};
}
+ runReadWriteTx<T, StoreNameArray extends Array<StoreNames<StoreMap>>>(
+ storeNames: StoreNameArray,
+ txf: (
+ tx: DbReadWriteTransactionArr<StoreMap, StoreNameArray>,
+ ) => Promise<T>,
+ ): Promise<T> {
+ const accessibleStores: { [x: string]: StoreWithIndexes<any, any, any> } =
+ {};
+ const strStoreNames: string[] = [];
+ for (const sn of storeNames) {
+ const swi = (this.stores as any)[sn] as StoreWithIndexes<any, any, any>;
+ strStoreNames.push(swi.storeName);
+ accessibleStores[swi.storeName] = swi;
+ }
+ const tx = this.db.transaction(strStoreNames, "readwrite");
+ const writeContext = makeWriteContext(tx, accessibleStores);
+ return runTx(tx, writeContext, txf);
+ }
+
+ runReadOnlyTx<T, StoreNameArray extends Array<StoreNames<StoreMap>>>(
+ storeNames: StoreNameArray,
+ txf: (tx: DbReadOnlyTransactionArr<StoreMap, StoreNameArray>) => Promise<T>,
+ ): Promise<T> {
+ const accessibleStores: { [x: string]: StoreWithIndexes<any, any, any> } =
+ {};
+ const strStoreNames: string[] = [];
+ for (const sn of storeNames) {
+ const swi = (this.stores as any)[sn] as StoreWithIndexes<any, any, any>;
+ strStoreNames.push(swi.storeName);
+ accessibleStores[swi.storeName] = swi;
+ }
+ const tx = this.db.transaction(strStoreNames, "readwrite");
+ const readContext = makeReadContext(tx, accessibleStores);
+ return runTx(tx, readContext, txf);
+ }
+
/**
* Run a transaction with selected object stores.
*