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