more static typing for transactions (fixes #6653)
This commit is contained in:
parent
2b19594e7a
commit
4e481a51c6
@ -285,7 +285,7 @@ async function processTipImpl(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
await ws.db.runWithWriteTransaction([Stores.planchets], async (tx) => {
|
await ws.db.runWithWriteTransaction([Stores.tips], async (tx) => {
|
||||||
const tipRecord = await tx.get(Stores.tips, walletTipId);
|
const tipRecord = await tx.get(Stores.tips, walletTipId);
|
||||||
if (!tipRecord) {
|
if (!tipRecord) {
|
||||||
return;
|
return;
|
||||||
|
@ -785,7 +785,7 @@ export interface CoinRecord {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Blinding key used when withdrawing the coin.
|
* Blinding key used when withdrawing the coin.
|
||||||
* Potentionally sed again during payback.
|
* Potentionally used again during payback.
|
||||||
*/
|
*/
|
||||||
blindingKey: string;
|
blindingKey: string;
|
||||||
|
|
||||||
@ -1531,135 +1531,160 @@ export enum ImportPayloadType {
|
|||||||
CoreSchema = "core-schema",
|
CoreSchema = "core-schema",
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExchangesStore extends Store<ExchangeRecord> {
|
class ExchangesStore extends Store<"exchanges", ExchangeRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("exchanges", { keyPath: "baseUrl" });
|
super("exchanges", { keyPath: "baseUrl" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CoinsStore extends Store<CoinRecord> {
|
class CoinsStore extends Store<"coins", CoinRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("coins", { keyPath: "coinPub" });
|
super("coins", { keyPath: "coinPub" });
|
||||||
}
|
}
|
||||||
|
|
||||||
exchangeBaseUrlIndex = new Index<string, CoinRecord>(
|
exchangeBaseUrlIndex = new Index<
|
||||||
this,
|
"coins",
|
||||||
"exchangeBaseUrl",
|
"exchangeBaseUrl",
|
||||||
"exchangeBaseUrl",
|
string,
|
||||||
);
|
CoinRecord
|
||||||
denomPubHashIndex = new Index<string, CoinRecord>(
|
>(this, "exchangeBaseUrl", "exchangeBaseUrl");
|
||||||
this,
|
|
||||||
|
denomPubHashIndex = new Index<
|
||||||
|
"coins",
|
||||||
"denomPubHashIndex",
|
"denomPubHashIndex",
|
||||||
"denomPubHash",
|
string,
|
||||||
);
|
CoinRecord
|
||||||
|
>(this, "denomPubHashIndex", "denomPubHash");
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProposalsStore extends Store<ProposalRecord> {
|
class ProposalsStore extends Store<"proposals", ProposalRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("proposals", { keyPath: "proposalId" });
|
super("proposals", { keyPath: "proposalId" });
|
||||||
}
|
}
|
||||||
urlAndOrderIdIndex = new Index<string, ProposalRecord>(this, "urlIndex", [
|
urlAndOrderIdIndex = new Index<
|
||||||
"merchantBaseUrl",
|
"proposals",
|
||||||
"orderId",
|
"urlIndex",
|
||||||
]);
|
string,
|
||||||
|
ProposalRecord
|
||||||
|
>(this, "urlIndex", ["merchantBaseUrl", "orderId"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PurchasesStore extends Store<PurchaseRecord> {
|
class PurchasesStore extends Store<"purchases", PurchaseRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("purchases", { keyPath: "proposalId" });
|
super("purchases", { keyPath: "proposalId" });
|
||||||
}
|
}
|
||||||
|
|
||||||
fulfillmentUrlIndex = new Index<string, PurchaseRecord>(
|
fulfillmentUrlIndex = new Index<
|
||||||
this,
|
"purchases",
|
||||||
"fulfillmentUrlIndex",
|
"fulfillmentUrlIndex",
|
||||||
"contractData.fulfillmentUrl",
|
string,
|
||||||
|
PurchaseRecord
|
||||||
|
>(this, "fulfillmentUrlIndex", "contractData.fulfillmentUrl");
|
||||||
|
|
||||||
|
orderIdIndex = new Index<"purchases", "orderIdIndex", string, PurchaseRecord>(
|
||||||
|
this,
|
||||||
|
"orderIdIndex",
|
||||||
|
["contractData.merchantBaseUrl", "contractData.orderId"],
|
||||||
);
|
);
|
||||||
orderIdIndex = new Index<string, PurchaseRecord>(this, "orderIdIndex", [
|
|
||||||
"contractData.merchantBaseUrl",
|
|
||||||
"contractData.orderId",
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DenominationsStore extends Store<DenominationRecord> {
|
class DenominationsStore extends Store<"denominations", DenominationRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
// cast needed because of bug in type annotations
|
// cast needed because of bug in type annotations
|
||||||
super("denominations", {
|
super("denominations", {
|
||||||
keyPath: (["exchangeBaseUrl", "denomPubHash"] as any) as IDBKeyPath,
|
keyPath: (["exchangeBaseUrl", "denomPubHash"] as any) as IDBKeyPath,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
exchangeBaseUrlIndex = new Index<string, DenominationRecord>(
|
exchangeBaseUrlIndex = new Index<
|
||||||
this,
|
"denominations",
|
||||||
"exchangeBaseUrlIndex",
|
"exchangeBaseUrlIndex",
|
||||||
"exchangeBaseUrl",
|
string,
|
||||||
);
|
DenominationRecord
|
||||||
|
>(this, "exchangeBaseUrlIndex", "exchangeBaseUrl");
|
||||||
}
|
}
|
||||||
|
|
||||||
class CurrenciesStore extends Store<CurrencyRecord> {
|
class CurrenciesStore extends Store<"currencies", CurrencyRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("currencies", { keyPath: "name" });
|
super("currencies", { keyPath: "name" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConfigStore extends Store<ConfigRecord> {
|
class ConfigStore extends Store<"config", ConfigRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("config", { keyPath: "key" });
|
super("config", { keyPath: "key" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReservesStore extends Store<ReserveRecord> {
|
class ReservesStore extends Store<"reserves", ReserveRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("reserves", { keyPath: "reservePub" });
|
super("reserves", { keyPath: "reservePub" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReserveHistoryStore extends Store<ReserveHistoryRecord> {
|
class ReserveHistoryStore extends Store<
|
||||||
|
"reserveHistory",
|
||||||
|
ReserveHistoryRecord
|
||||||
|
> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("reserveHistory", { keyPath: "reservePub" });
|
super("reserveHistory", { keyPath: "reservePub" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TipsStore extends Store<TipRecord> {
|
class TipsStore extends Store<"tips", TipRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("tips", { keyPath: "walletTipId" });
|
super("tips", { keyPath: "walletTipId" });
|
||||||
}
|
}
|
||||||
// Added in version 2
|
// Added in version 2
|
||||||
byMerchantTipIdAndBaseUrl = new Index<[string, string], TipRecord>(
|
byMerchantTipIdAndBaseUrl = new Index<
|
||||||
|
"tips",
|
||||||
|
"tipsByMerchantTipIdAndOriginIndex",
|
||||||
|
[string, string],
|
||||||
|
TipRecord
|
||||||
|
>(
|
||||||
this,
|
this,
|
||||||
"tipsByMerchantTipIdAndOriginIndex",
|
"tipsByMerchantTipIdAndOriginIndex",
|
||||||
["merchantTipId", "merchantBaseUrl"],
|
["merchantTipId", "merchantBaseUrl"],
|
||||||
{
|
{
|
||||||
versionAdded: 2,
|
versionAdded: 2,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class WithdrawalGroupsStore extends Store<WithdrawalGroupRecord> {
|
class WithdrawalGroupsStore extends Store<
|
||||||
|
"withdrawals",
|
||||||
|
WithdrawalGroupRecord
|
||||||
|
> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("withdrawals", { keyPath: "withdrawalGroupId" });
|
super("withdrawals", { keyPath: "withdrawalGroupId" });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlanchetsStore extends Store<PlanchetRecord> {
|
class PlanchetsStore extends Store<"planchets", PlanchetRecord> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("planchets", { keyPath: "coinPub" });
|
super("planchets", { keyPath: "coinPub" });
|
||||||
}
|
}
|
||||||
byGroupAndIndex = new Index<string, PlanchetRecord>(
|
byGroupAndIndex = new Index<
|
||||||
this,
|
"planchets",
|
||||||
"withdrawalGroupAndCoinIdxIndex",
|
"withdrawalGroupAndCoinIdxIndex",
|
||||||
["withdrawalGroupId", "coinIdx"],
|
string,
|
||||||
);
|
PlanchetRecord
|
||||||
byGroup = new Index<string, PlanchetRecord>(
|
>(this, "withdrawalGroupAndCoinIdxIndex", ["withdrawalGroupId", "coinIdx"]);
|
||||||
this,
|
byGroup = new Index<
|
||||||
|
"planchets",
|
||||||
"withdrawalGroupIndex",
|
"withdrawalGroupIndex",
|
||||||
"withdrawalGroupId",
|
string,
|
||||||
);
|
PlanchetRecord
|
||||||
|
>(this, "withdrawalGroupIndex", "withdrawalGroupId");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This store is effectively a materialized index for
|
* This store is effectively a materialized index for
|
||||||
* reserve records that are for a bank-integrated withdrawal.
|
* reserve records that are for a bank-integrated withdrawal.
|
||||||
*/
|
*/
|
||||||
class BankWithdrawUrisStore extends Store<BankWithdrawUriRecord> {
|
class BankWithdrawUrisStore extends Store<
|
||||||
|
"bankWithdrawUris",
|
||||||
|
BankWithdrawUriRecord
|
||||||
|
> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super("bankWithdrawUris", { keyPath: "talerWithdrawUri" });
|
super("bankWithdrawUris", { keyPath: "talerWithdrawUri" });
|
||||||
}
|
}
|
||||||
@ -1675,10 +1700,13 @@ export const Stores = {
|
|||||||
denominations: new DenominationsStore(),
|
denominations: new DenominationsStore(),
|
||||||
exchanges: new ExchangesStore(),
|
exchanges: new ExchangesStore(),
|
||||||
proposals: new ProposalsStore(),
|
proposals: new ProposalsStore(),
|
||||||
refreshGroups: new Store<RefreshGroupRecord>("refreshGroups", {
|
refreshGroups: new Store<"refreshGroups", RefreshGroupRecord>(
|
||||||
keyPath: "refreshGroupId",
|
"refreshGroups",
|
||||||
}),
|
{
|
||||||
recoupGroups: new Store<RecoupGroupRecord>("recoupGroups", {
|
keyPath: "refreshGroupId",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
recoupGroups: new Store<"recoupGroups", RecoupGroupRecord>("recoupGroups", {
|
||||||
keyPath: "recoupGroupId",
|
keyPath: "recoupGroupId",
|
||||||
}),
|
}),
|
||||||
reserves: new ReservesStore(),
|
reserves: new ReservesStore(),
|
||||||
|
@ -59,11 +59,8 @@ export interface StoreParams<T> {
|
|||||||
/**
|
/**
|
||||||
* Definition of an object store.
|
* Definition of an object store.
|
||||||
*/
|
*/
|
||||||
export class Store<T> {
|
export class Store<N extends string, T> {
|
||||||
constructor(
|
constructor(public name: N, public storeParams?: StoreParams<T>) {}
|
||||||
public name: string,
|
|
||||||
public storeParams?: StoreParams<T>,
|
|
||||||
) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -273,26 +270,48 @@ class ResultStream<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TransactionHandle {
|
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, {}>> {
|
||||||
constructor(private tx: IDBTransaction) {}
|
constructor(private tx: IDBTransaction) {}
|
||||||
|
|
||||||
put<T>(store: Store<T>, value: T, key?: any): Promise<any> {
|
put<S extends StoreTypes>(
|
||||||
|
store: S,
|
||||||
|
value: StoreContent<S>,
|
||||||
|
key?: any,
|
||||||
|
): Promise<any> {
|
||||||
const req = this.tx.objectStore(store.name).put(value, key);
|
const req = this.tx.objectStore(store.name).put(value, key);
|
||||||
return requestToPromise(req);
|
return requestToPromise(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
add<T>(store: Store<T>, value: T, key?: any): Promise<any> {
|
add<S extends StoreTypes>(
|
||||||
|
store: S,
|
||||||
|
value: StoreContent<S>,
|
||||||
|
key?: any,
|
||||||
|
): Promise<any> {
|
||||||
const req = this.tx.objectStore(store.name).add(value, key);
|
const req = this.tx.objectStore(store.name).add(value, key);
|
||||||
return requestToPromise(req);
|
return requestToPromise(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
get<T>(store: Store<T>, key: any): Promise<T | undefined> {
|
get<S extends StoreTypes>(
|
||||||
|
store: S,
|
||||||
|
key: any,
|
||||||
|
): Promise<StoreContent<S> | undefined> {
|
||||||
const req = this.tx.objectStore(store.name).get(key);
|
const req = this.tx.objectStore(store.name).get(key);
|
||||||
return requestToPromise(req);
|
return requestToPromise(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
getIndexed<S extends IDBValidKey, T>(
|
getIndexed<
|
||||||
index: Index<S, T>,
|
StoreName extends StrKey<StoreTypes>,
|
||||||
|
IndexName extends string,
|
||||||
|
S extends IDBValidKey,
|
||||||
|
T
|
||||||
|
>(
|
||||||
|
index: Index<StoreName, IndexName, S, T>,
|
||||||
key: any,
|
key: any,
|
||||||
): Promise<T | undefined> {
|
): Promise<T | undefined> {
|
||||||
const req = this.tx
|
const req = this.tx
|
||||||
@ -302,15 +321,20 @@ export class TransactionHandle {
|
|||||||
return requestToPromise(req);
|
return requestToPromise(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
iter<T>(store: Store<T>, key?: any): ResultStream<T> {
|
iter<N extends StrKey<StoreTypes>, T extends StoreTypes[N]>(
|
||||||
|
store: Store<N, T>,
|
||||||
|
key?: any,
|
||||||
|
): ResultStream<T> {
|
||||||
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<T>(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterIndexed<S extends IDBValidKey, T>(
|
iterIndexed<
|
||||||
index: Index<S, T>,
|
StoreName extends StrKey<StoreTypes>,
|
||||||
key?: any,
|
IndexName extends string,
|
||||||
): ResultStream<T> {
|
S extends IDBValidKey,
|
||||||
|
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)
|
||||||
@ -318,13 +342,16 @@ export class TransactionHandle {
|
|||||||
return new ResultStream<T>(req);
|
return new ResultStream<T>(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete<T>(store: Store<T>, key: any): Promise<void> {
|
delete<N extends StrKey<StoreTypes>, T extends StoreTypes[N]>(
|
||||||
|
store: Store<N, T>,
|
||||||
|
key: any,
|
||||||
|
): 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<T>(
|
mutate<N extends StrKey<StoreTypes>, T extends StoreTypes[N]>(
|
||||||
store: Store<T>,
|
store: Store<N, T>,
|
||||||
key: any,
|
key: any,
|
||||||
f: (x: T) => T | undefined,
|
f: (x: T) => T | undefined,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@ -333,10 +360,10 @@ export class TransactionHandle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function runWithTransaction<T>(
|
function runWithTransaction<T, StoreTypes extends Store<string, {}>>(
|
||||||
db: IDBDatabase,
|
db: IDBDatabase,
|
||||||
stores: Store<any>[],
|
stores: StoreTypes[],
|
||||||
f: (t: TransactionHandle) => Promise<T>,
|
f: (t: TransactionHandle<StoreTypes>) => Promise<T>,
|
||||||
mode: "readonly" | "readwrite",
|
mode: "readonly" | "readwrite",
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
const stack = Error("Failed transaction was started here.");
|
const stack = Error("Failed transaction was started here.");
|
||||||
@ -397,7 +424,12 @@ function runWithTransaction<T>(
|
|||||||
/**
|
/**
|
||||||
* Definition of an index.
|
* Definition of an index.
|
||||||
*/
|
*/
|
||||||
export class Index<S extends IDBValidKey, T> {
|
export class Index<
|
||||||
|
StoreName extends string,
|
||||||
|
IndexName extends string,
|
||||||
|
S extends IDBValidKey,
|
||||||
|
T
|
||||||
|
> {
|
||||||
/**
|
/**
|
||||||
* Name of the store that this index is associated with.
|
* Name of the store that this index is associated with.
|
||||||
*/
|
*/
|
||||||
@ -409,8 +441,8 @@ export class Index<S extends IDBValidKey, T> {
|
|||||||
options: IndexOptions;
|
options: IndexOptions;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
s: Store<T>,
|
s: Store<StoreName, T>,
|
||||||
public indexName: string,
|
public indexName: IndexName,
|
||||||
public keyPath: string | string[],
|
public keyPath: string | string[],
|
||||||
options?: IndexOptions,
|
options?: IndexOptions,
|
||||||
) {
|
) {
|
||||||
@ -539,7 +571,10 @@ export class Database {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async get<T>(store: Store<T>, key: any): Promise<T | undefined> {
|
async get<N extends string, T>(
|
||||||
|
store: Store<N, T>,
|
||||||
|
key: any,
|
||||||
|
): Promise<T | undefined> {
|
||||||
const tx = this.db.transaction([store.name], "readonly");
|
const tx = this.db.transaction([store.name], "readonly");
|
||||||
const req = tx.objectStore(store.name).get(key);
|
const req = tx.objectStore(store.name).get(key);
|
||||||
const v = await requestToPromise(req);
|
const v = await requestToPromise(req);
|
||||||
@ -547,10 +582,12 @@ export class Database {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getIndexed<S extends IDBValidKey, T>(
|
async getIndexed<Ind extends Index<string, string, any, any>>(
|
||||||
index: Index<S, T>,
|
index: Ind extends Index<infer IndN, infer StN, any, infer R>
|
||||||
|
? Index<IndN, StN, any, R>
|
||||||
|
: never,
|
||||||
key: any,
|
key: any,
|
||||||
): Promise<T | undefined> {
|
): Promise<IndexRecord<Ind> | undefined> {
|
||||||
const tx = this.db.transaction([index.storeName], "readonly");
|
const tx = this.db.transaction([index.storeName], "readonly");
|
||||||
const req = tx.objectStore(index.storeName).index(index.indexName).get(key);
|
const req = tx.objectStore(index.storeName).index(index.indexName).get(key);
|
||||||
const v = await requestToPromise(req);
|
const v = await requestToPromise(req);
|
||||||
@ -558,7 +595,11 @@ export class Database {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
async put<T>(store: Store<T>, value: T, key?: any): Promise<any> {
|
async put<St extends Store<string, any>>(
|
||||||
|
store: St extends Store<infer N, infer R> ? Store<N, R> : never,
|
||||||
|
value: St extends Store<any, infer R> ? R : never,
|
||||||
|
key?: any,
|
||||||
|
): Promise<any> {
|
||||||
const tx = this.db.transaction([store.name], "readwrite");
|
const tx = this.db.transaction([store.name], "readwrite");
|
||||||
const req = tx.objectStore(store.name).put(value, key);
|
const req = tx.objectStore(store.name).put(value, key);
|
||||||
const v = await requestToPromise(req);
|
const v = await requestToPromise(req);
|
||||||
@ -566,8 +607,8 @@ export class Database {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
async mutate<T>(
|
async mutate<N extends string, T>(
|
||||||
store: Store<T>,
|
store: Store<N, T>,
|
||||||
key: any,
|
key: any,
|
||||||
f: (x: T) => T | undefined,
|
f: (x: T) => T | undefined,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@ -577,14 +618,14 @@ export class Database {
|
|||||||
await transactionToPromise(tx);
|
await transactionToPromise(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
iter<T>(store: Store<T>): ResultStream<T> {
|
iter<N extends string, T>(store: Store<N, T>): ResultStream<T> {
|
||||||
const tx = this.db.transaction([store.name], "readonly");
|
const tx = this.db.transaction([store.name], "readonly");
|
||||||
const req = tx.objectStore(store.name).openCursor();
|
const req = tx.objectStore(store.name).openCursor();
|
||||||
return new ResultStream<T>(req);
|
return new ResultStream<T>(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterIndex<S extends IDBValidKey, T>(
|
iterIndex<N extends string, I extends string, S extends IDBValidKey, T>(
|
||||||
index: Index<S, T>,
|
index: Index<N, I, S, T>,
|
||||||
query?: any,
|
query?: any,
|
||||||
): ResultStream<T> {
|
): ResultStream<T> {
|
||||||
const tx = this.db.transaction([index.storeName], "readonly");
|
const tx = this.db.transaction([index.storeName], "readonly");
|
||||||
@ -595,17 +636,17 @@ export class Database {
|
|||||||
return new ResultStream<T>(req);
|
return new ResultStream<T>(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
async runWithReadTransaction<T>(
|
async runWithReadTransaction<T, StoreTypes extends Store<string, any>>(
|
||||||
stores: Store<any>[],
|
stores: StoreTypes[],
|
||||||
f: (t: TransactionHandle) => Promise<T>,
|
f: (t: TransactionHandle<StoreTypes>) => Promise<T>,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
return runWithTransaction<T>(this.db, stores, f, "readonly");
|
return runWithTransaction<T, StoreTypes>(this.db, stores, f, "readonly");
|
||||||
}
|
}
|
||||||
|
|
||||||
async runWithWriteTransaction<T>(
|
async runWithWriteTransaction<T, StoreTypes extends Store<string, any>>(
|
||||||
stores: Store<any>[],
|
stores: StoreTypes[],
|
||||||
f: (t: TransactionHandle) => Promise<T>,
|
f: (t: TransactionHandle<StoreTypes>) => Promise<T>,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
return runWithTransaction<T>(this.db, stores, f, "readwrite");
|
return runWithTransaction<T, StoreTypes>(this.db, stores, f, "readwrite");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user