fix static types
This commit is contained in:
parent
4e481a51c6
commit
0828e65f88
@ -39,11 +39,11 @@ export function openTalerDatabase(
|
||||
if (oldVersion === 0) {
|
||||
for (const n in Stores) {
|
||||
if ((Stores as any)[n] instanceof Store) {
|
||||
const si: Store<any> = (Stores as any)[n];
|
||||
const si: Store<string, any> = (Stores as any)[n];
|
||||
const s = db.createObjectStore(si.name, si.storeParams);
|
||||
for (const indexName in si as any) {
|
||||
if ((si as any)[indexName] instanceof Index) {
|
||||
const ii: Index<any, any> = (si as any)[indexName];
|
||||
const ii: Index<string, string, any, any> = (si as any)[indexName];
|
||||
s.createIndex(ii.indexName, ii.keyPath, ii.options);
|
||||
}
|
||||
}
|
||||
@ -57,7 +57,7 @@ export function openTalerDatabase(
|
||||
logger.info(`upgrading database from ${oldVersion} to ${newVersion}`);
|
||||
for (const n in Stores) {
|
||||
if ((Stores as any)[n] instanceof Store) {
|
||||
const si: Store<any> = (Stores as any)[n];
|
||||
const si: Store<string, any> = (Stores as any)[n];
|
||||
let s: IDBObjectStore;
|
||||
if ((si.storeParams?.versionAdded ?? 1) > oldVersion) {
|
||||
s = db.createObjectStore(si.name, si.storeParams);
|
||||
@ -66,7 +66,7 @@ export function openTalerDatabase(
|
||||
}
|
||||
for (const indexName in si as any) {
|
||||
if ((si as any)[indexName] instanceof Index) {
|
||||
const ii: Index<any, any> = (si as any)[indexName];
|
||||
const ii: Index<string, string, any, any> = (si as any)[indexName];
|
||||
if ((ii.options?.versionAdded ?? 0) > oldVersion) {
|
||||
s.createIndex(ii.indexName, ii.keyPath, ii.options);
|
||||
}
|
||||
|
@ -38,7 +38,13 @@ interface WalletBalance {
|
||||
*/
|
||||
export async function getBalancesInsideTransaction(
|
||||
ws: InternalWalletState,
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<
|
||||
| typeof Stores.reserves
|
||||
| typeof Stores.coins
|
||||
| typeof Stores.reserves
|
||||
| typeof Stores.refreshGroups
|
||||
| typeof Stores.withdrawalGroups
|
||||
>,
|
||||
): Promise<BalancesResponse> {
|
||||
const balanceStore: Record<string, WalletBalance> = {};
|
||||
|
||||
|
@ -37,7 +37,7 @@ import {
|
||||
getDurationRemaining,
|
||||
durationMin,
|
||||
} from "../util/time";
|
||||
import { TransactionHandle } from "../util/query";
|
||||
import { Store, TransactionHandle } from "../util/query";
|
||||
import { InternalWalletState } from "./state";
|
||||
import { getBalancesInsideTransaction } from "./balance";
|
||||
|
||||
@ -52,7 +52,7 @@ function updateRetryDelay(
|
||||
}
|
||||
|
||||
async function gatherExchangePending(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.exchanges>,
|
||||
now: Timestamp,
|
||||
resp: PendingOperationsResponse,
|
||||
onlyDue = false,
|
||||
@ -171,7 +171,7 @@ async function gatherExchangePending(
|
||||
}
|
||||
|
||||
async function gatherReservePending(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.reserves>,
|
||||
now: Timestamp,
|
||||
resp: PendingOperationsResponse,
|
||||
onlyDue = false,
|
||||
@ -226,7 +226,7 @@ async function gatherReservePending(
|
||||
}
|
||||
|
||||
async function gatherRefreshPending(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.refreshGroups>,
|
||||
now: Timestamp,
|
||||
resp: PendingOperationsResponse,
|
||||
onlyDue = false,
|
||||
@ -255,7 +255,7 @@ async function gatherRefreshPending(
|
||||
}
|
||||
|
||||
async function gatherWithdrawalPending(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.withdrawalGroups>,
|
||||
now: Timestamp,
|
||||
resp: PendingOperationsResponse,
|
||||
onlyDue = false,
|
||||
@ -295,7 +295,7 @@ async function gatherWithdrawalPending(
|
||||
}
|
||||
|
||||
async function gatherProposalPending(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.proposals>,
|
||||
now: Timestamp,
|
||||
resp: PendingOperationsResponse,
|
||||
onlyDue = false,
|
||||
@ -346,7 +346,7 @@ async function gatherProposalPending(
|
||||
}
|
||||
|
||||
async function gatherTipPending(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.tips>,
|
||||
now: Timestamp,
|
||||
resp: PendingOperationsResponse,
|
||||
onlyDue = false,
|
||||
@ -376,7 +376,7 @@ async function gatherTipPending(
|
||||
}
|
||||
|
||||
async function gatherPurchasePending(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.purchases>,
|
||||
now: Timestamp,
|
||||
resp: PendingOperationsResponse,
|
||||
onlyDue = false,
|
||||
@ -419,7 +419,7 @@ async function gatherPurchasePending(
|
||||
}
|
||||
|
||||
async function gatherRecoupPending(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.recoupGroups>,
|
||||
now: Timestamp,
|
||||
resp: PendingOperationsResponse,
|
||||
onlyDue = false,
|
||||
|
@ -46,7 +46,7 @@ import {
|
||||
import { Amounts } from "../util/amounts";
|
||||
import { createRefreshGroup, processRefreshGroup } from "./refresh";
|
||||
import { RefreshReason, TalerErrorDetails } from "../types/walletTypes";
|
||||
import { TransactionHandle } from "../util/query";
|
||||
import { Store, StoreParams, TransactionHandle } from "../util/query";
|
||||
import { encodeCrock, getRandomBytes } from "../crypto/talerCrypto";
|
||||
import { getTimestampNow } from "../util/time";
|
||||
import { guardOperationException } from "./errors";
|
||||
@ -82,7 +82,7 @@ async function incrementRecoupRetry(
|
||||
|
||||
async function putGroupAsFinished(
|
||||
ws: InternalWalletState,
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.recoupGroups>,
|
||||
recoupGroup: RecoupGroupRecord,
|
||||
coinIdx: number,
|
||||
): Promise<void> {
|
||||
@ -366,7 +366,7 @@ async function processRecoupGroupImpl(
|
||||
|
||||
export async function createRecoupGroup(
|
||||
ws: InternalWalletState,
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.recoupGroups | typeof Stores.coins>,
|
||||
coinPubs: string[],
|
||||
): Promise<string> {
|
||||
const recoupGroupId = encodeCrock(getRandomBytes(32));
|
||||
|
@ -52,9 +52,7 @@ import {
|
||||
durationMax,
|
||||
durationMul,
|
||||
} from "../util/time";
|
||||
import {
|
||||
readSuccessResponseJsonOrThrow,
|
||||
} from "../util/http";
|
||||
import { readSuccessResponseJsonOrThrow } from "../util/http";
|
||||
import {
|
||||
codecForExchangeMeltResponse,
|
||||
codecForExchangeRevealResponse,
|
||||
@ -567,7 +565,11 @@ async function processRefreshSession(
|
||||
*/
|
||||
export async function createRefreshGroup(
|
||||
ws: InternalWalletState,
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<
|
||||
| typeof Stores.denominations
|
||||
| typeof Stores.coins
|
||||
| typeof Stores.refreshGroups
|
||||
>,
|
||||
oldCoinPubs: CoinPublicKey[],
|
||||
reason: RefreshReason,
|
||||
): Promise<RefreshGroupId> {
|
||||
|
@ -103,7 +103,7 @@ function getRefundKey(d: MerchantCoinRefundStatus): string {
|
||||
}
|
||||
|
||||
async function applySuccessfulRefund(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.coins | typeof Stores.denominations>,
|
||||
p: PurchaseRecord,
|
||||
refreshCoinsMap: Record<string, { coinPub: string }>,
|
||||
r: MerchantCoinRefundSuccessStatus,
|
||||
@ -162,7 +162,7 @@ async function applySuccessfulRefund(
|
||||
}
|
||||
|
||||
async function storePendingRefund(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.denominations | typeof Stores.coins>,
|
||||
p: PurchaseRecord,
|
||||
r: MerchantCoinRefundFailureStatus,
|
||||
): Promise<void> {
|
||||
@ -212,7 +212,7 @@ async function storePendingRefund(
|
||||
}
|
||||
|
||||
async function storeFailedRefund(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.coins | typeof Stores.denominations>,
|
||||
p: PurchaseRecord,
|
||||
refreshCoinsMap: Record<string, { coinPub: string }>,
|
||||
r: MerchantCoinRefundFailureStatus,
|
||||
|
@ -81,7 +81,11 @@ import {
|
||||
} from "../util/http";
|
||||
import { codecForAny } from "../util/codec";
|
||||
import { URL } from "../util/url";
|
||||
import { initRetryInfo, getRetryDuration, updateRetryInfoTimeout } from "../util/retries";
|
||||
import {
|
||||
initRetryInfo,
|
||||
getRetryDuration,
|
||||
updateRetryInfoTimeout,
|
||||
} from "../util/retries";
|
||||
|
||||
const logger = new Logger("reserves.ts");
|
||||
|
||||
@ -523,7 +527,8 @@ async function updateReserve(
|
||||
if (result.isError) {
|
||||
if (
|
||||
resp.status === 404 &&
|
||||
result.talerErrorResponse.code === TalerErrorCode.EXCHANGE_RESERVES_GET_STATUS_UNKNOWN
|
||||
result.talerErrorResponse.code ===
|
||||
TalerErrorCode.EXCHANGE_RESERVES_GET_STATUS_UNKNOWN
|
||||
) {
|
||||
ws.notify({
|
||||
type: NotificationType.ReserveNotYetFound,
|
||||
@ -863,7 +868,7 @@ export async function createTalerWithdrawReserve(
|
||||
* Get payto URIs needed to fund a reserve.
|
||||
*/
|
||||
export async function getFundingPaytoUris(
|
||||
tx: TransactionHandle,
|
||||
tx: TransactionHandle<typeof Stores.reserves | typeof Stores.exchanges>,
|
||||
reservePub: string,
|
||||
): Promise<string[]> {
|
||||
const r = await tx.get(Stores.reserves, reservePub);
|
||||
|
@ -270,13 +270,21 @@ class ResultStream<T> {
|
||||
}
|
||||
}
|
||||
|
||||
type StrKey<T> = string & keyof T;
|
||||
|
||||
type StoreName<S> = S extends Store<infer N, any> ? N : never;
|
||||
type StoreContent<S> = S extends Store<any, infer R> ? R : never;
|
||||
type IndexRecord<Ind> = Ind extends Index<any, any, any, infer R> ? R : never;
|
||||
|
||||
export class TransactionHandle<StoreTypes extends Store<string, {}>> {
|
||||
type InferStore<S> = S extends Store<infer N, infer R> ? Store<N, R> : never;
|
||||
type InferIndex<Ind> = Ind extends Index<
|
||||
infer StN,
|
||||
infer IndN,
|
||||
infer KT,
|
||||
infer RT
|
||||
>
|
||||
? Index<StN, IndN, KT, RT>
|
||||
: never;
|
||||
|
||||
export class TransactionHandle<StoreTypes extends Store<string, any>> {
|
||||
constructor(private tx: IDBTransaction) {}
|
||||
|
||||
put<S extends StoreTypes>(
|
||||
@ -306,14 +314,9 @@ export class TransactionHandle<StoreTypes extends Store<string, {}>> {
|
||||
}
|
||||
|
||||
getIndexed<
|
||||
StoreName extends StrKey<StoreTypes>,
|
||||
IndexName extends string,
|
||||
S extends IDBValidKey,
|
||||
T
|
||||
>(
|
||||
index: Index<StoreName, IndexName, S, T>,
|
||||
key: any,
|
||||
): Promise<T | undefined> {
|
||||
St extends StoreTypes,
|
||||
Ind extends Index<StoreName<St>, string, any, any>
|
||||
>(index: InferIndex<Ind>, key: any): Promise<IndexRecord<Ind> | undefined> {
|
||||
const req = this.tx
|
||||
.objectStore(index.storeName)
|
||||
.index(index.indexName)
|
||||
@ -321,39 +324,37 @@ export class TransactionHandle<StoreTypes extends Store<string, {}>> {
|
||||
return requestToPromise(req);
|
||||
}
|
||||
|
||||
iter<N extends StrKey<StoreTypes>, T extends StoreTypes[N]>(
|
||||
store: Store<N, T>,
|
||||
iter<St extends InferStore<StoreTypes>>(
|
||||
store: St,
|
||||
key?: any,
|
||||
): ResultStream<T> {
|
||||
): ResultStream<StoreContent<St>> {
|
||||
const req = this.tx.objectStore(store.name).openCursor(key);
|
||||
return new ResultStream<T>(req);
|
||||
return new ResultStream<StoreContent<St>>(req);
|
||||
}
|
||||
|
||||
iterIndexed<
|
||||
StoreName extends StrKey<StoreTypes>,
|
||||
IndexName extends string,
|
||||
S extends IDBValidKey,
|
||||
T
|
||||
>(index: Index<StoreName, IndexName, S, T>, key?: any): ResultStream<T> {
|
||||
St extends InferStore<StoreTypes>,
|
||||
Ind extends InferIndex<Index<StoreName<St>, string, any, any>>
|
||||
>(index: Ind, key?: any): ResultStream<IndexRecord<Ind>> {
|
||||
const req = this.tx
|
||||
.objectStore(index.storeName)
|
||||
.index(index.indexName)
|
||||
.openCursor(key);
|
||||
return new ResultStream<T>(req);
|
||||
return new ResultStream<IndexRecord<Ind>>(req);
|
||||
}
|
||||
|
||||
delete<N extends StrKey<StoreTypes>, T extends StoreTypes[N]>(
|
||||
store: Store<N, T>,
|
||||
delete<St extends StoreTypes>(
|
||||
store: InferStore<St>,
|
||||
key: any,
|
||||
): Promise<void> {
|
||||
const req = this.tx.objectStore(store.name).delete(key);
|
||||
return requestToPromise(req);
|
||||
}
|
||||
|
||||
mutate<N extends StrKey<StoreTypes>, T extends StoreTypes[N]>(
|
||||
store: Store<N, T>,
|
||||
mutate<St extends StoreTypes>(
|
||||
store: InferStore<St>,
|
||||
key: any,
|
||||
f: (x: T) => T | undefined,
|
||||
f: (x: StoreContent<St>) => StoreContent<St> | undefined,
|
||||
): Promise<void> {
|
||||
const req = this.tx.objectStore(store.name).openCursor(key);
|
||||
return applyMutation(req, f);
|
||||
@ -583,9 +584,7 @@ export class Database {
|
||||
}
|
||||
|
||||
async getIndexed<Ind extends Index<string, string, any, any>>(
|
||||
index: Ind extends Index<infer IndN, infer StN, any, infer R>
|
||||
? Index<IndN, StN, any, R>
|
||||
: never,
|
||||
index: InferIndex<Ind>,
|
||||
key: any,
|
||||
): Promise<IndexRecord<Ind> | undefined> {
|
||||
const tx = this.db.transaction([index.storeName], "readonly");
|
||||
@ -624,16 +623,16 @@ export class Database {
|
||||
return new ResultStream<T>(req);
|
||||
}
|
||||
|
||||
iterIndex<N extends string, I extends string, S extends IDBValidKey, T>(
|
||||
index: Index<N, I, S, T>,
|
||||
iterIndex<Ind extends Index<string, string, any, any>>(
|
||||
index: InferIndex<Ind>,
|
||||
query?: any,
|
||||
): ResultStream<T> {
|
||||
): ResultStream<IndexRecord<Ind>> {
|
||||
const tx = this.db.transaction([index.storeName], "readonly");
|
||||
const req = tx
|
||||
.objectStore(index.storeName)
|
||||
.index(index.indexName)
|
||||
.openCursor(query);
|
||||
return new ResultStream<T>(req);
|
||||
return new ResultStream<IndexRecord<Ind>>(req);
|
||||
}
|
||||
|
||||
async runWithReadTransaction<T, StoreTypes extends Store<string, any>>(
|
||||
|
Loading…
Reference in New Issue
Block a user