diff options
author | Florian Dold <florian@dold.me> | 2024-01-09 16:23:26 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2024-01-09 16:23:26 +0100 |
commit | f8cde03f0cb6a7584fb92885f8979a01916a917d (patch) | |
tree | 6f120387f8f5297f436e2d2bd2d4d7b5c1814146 /packages/taler-wallet-core/src/util | |
parent | de39d432374a3ecd1bddd788b1ac1585461af8c1 (diff) | |
download | wallet-core-f8cde03f0cb6a7584fb92885f8979a01916a917d.tar.xz |
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.ts | 12 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/util/query.ts | 98 |
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. * |