@lunarislab/state-sync 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/classes/Client.d.ts +30 -0
- package/classes/Client.js +117 -0
- package/classes/Watcher.d.ts +27 -0
- package/classes/Watcher.js +89 -0
- package/index.d.ts +4 -0
- package/index.js +20 -0
- package/package.json +25 -0
- package/types/Client.d.ts +21 -0
- package/types/Client.js +4 -0
- package/types/Watcher.d.ts +131 -0
- package/types/Watcher.js +5 -0
package/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
import { AbiEvent, GetLogsReturnType, PublicClient, WalletClient } from "viem";
|
2
|
+
import { IClientConfig, IStateSyncEvents } from "../types/Client";
|
3
|
+
import { Watcher } from "./Watcher";
|
4
|
+
import { ISimplifiedWatcher, IWatcherConfig, LevelDBConstructor } from "../types/Watcher";
|
5
|
+
import { EventSignature } from "abitype/dist/types/human-readable/types/signatures";
|
6
|
+
import { EventEmitter } from "events";
|
7
|
+
/**
|
8
|
+
* The StateSync client class.
|
9
|
+
*/
|
10
|
+
export declare class StateSync implements IClientConfig {
|
11
|
+
public: PublicClient;
|
12
|
+
wallet: WalletClient;
|
13
|
+
level: LevelDBConstructor;
|
14
|
+
levelPath: string;
|
15
|
+
timeout: number;
|
16
|
+
protected watchers: Map<string, Watcher<any>>;
|
17
|
+
protected emitter: EventEmitter;
|
18
|
+
protected startBlockNum: bigint;
|
19
|
+
protected syncedBlockNum: bigint;
|
20
|
+
protected gap: bigint;
|
21
|
+
protected lastBlockNum: bigint;
|
22
|
+
protected eventCount: bigint;
|
23
|
+
constructor(config: IClientConfig);
|
24
|
+
protected _setInitialBlockNumbers(): Promise<import("viem").WatchBlocksReturnType>;
|
25
|
+
protected _processLogs(logs: GetLogsReturnType<undefined, AbiEvent[]>): Promise<void>;
|
26
|
+
protected _sync(): Promise<void>;
|
27
|
+
on<T extends keyof IStateSyncEvents>(eventName: T, callback: IStateSyncEvents[T]): EventEmitter;
|
28
|
+
start(): Promise<import("viem").WatchBlocksReturnType>;
|
29
|
+
createWatcher<Signature extends EventSignature>(config: IWatcherConfig<Signature>): Promise<ISimplifiedWatcher>;
|
30
|
+
}
|
@@ -0,0 +1,117 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.StateSync = void 0;
|
4
|
+
const viem_1 = require("viem");
|
5
|
+
const Watcher_1 = require("./Watcher");
|
6
|
+
const events_1 = require("events");
|
7
|
+
/**
|
8
|
+
* The StateSync client class.
|
9
|
+
*/
|
10
|
+
class StateSync {
|
11
|
+
constructor(config) {
|
12
|
+
this.watchers = new Map();
|
13
|
+
this.startBlockNum = 0n;
|
14
|
+
this.syncedBlockNum = 0n;
|
15
|
+
this.gap = 500000n;
|
16
|
+
this.lastBlockNum = 0n;
|
17
|
+
this.eventCount = 0n;
|
18
|
+
this.public = config.public;
|
19
|
+
this.wallet = config.wallet;
|
20
|
+
this.level = config.level;
|
21
|
+
this.levelPath = config.levelPath || "";
|
22
|
+
this.emitter = new events_1.EventEmitter();
|
23
|
+
this.timeout = config.timeout || 50;
|
24
|
+
}
|
25
|
+
;
|
26
|
+
async _setInitialBlockNumbers() {
|
27
|
+
const lastSyncedBlocksNumbers = Array.from(this.watchers.values()).map(s => s.lastSyncedBlockNumber);
|
28
|
+
const smalledSyncedBlockNumber = lastSyncedBlocksNumbers.reduce((min, value) => (value < min ? value : min));
|
29
|
+
this.startBlockNum = smalledSyncedBlockNumber;
|
30
|
+
this.syncedBlockNum = smalledSyncedBlockNumber;
|
31
|
+
this.lastBlockNum = await this.public.getBlockNumber();
|
32
|
+
return this.public.watchBlocks({ onBlock: (block) => this.lastBlockNum = block.number });
|
33
|
+
}
|
34
|
+
;
|
35
|
+
async _processLogs(logs) {
|
36
|
+
// Send logs to watcher classes to handle the storing logic.
|
37
|
+
for (const watcher of this.watchers.values()) {
|
38
|
+
const eventName = watcher.event.name;
|
39
|
+
const watcherLogs = logs.filter(log => watcher.addresses.includes((0, viem_1.checksumAddress)(log.address)) && log.eventName === eventName);
|
40
|
+
// make sure logs are well ordered by logIndex
|
41
|
+
watcherLogs.sort((a, b) => a.logIndex - b.logIndex);
|
42
|
+
await watcher.onLogs(watcherLogs);
|
43
|
+
await watcher.setSyncedBlockNumber(this.syncedBlockNum);
|
44
|
+
}
|
45
|
+
}
|
46
|
+
;
|
47
|
+
async _sync() {
|
48
|
+
const stopInitialWatcher = await this._setInitialBlockNumbers();
|
49
|
+
const contractsAddresses = Array.from(this.watchers.values()).map(s => s.addresses).flat(1);
|
50
|
+
const eventsABI = Array.from(this.watchers.values()).map(s => s.event);
|
51
|
+
while (this.syncedBlockNum < this.lastBlockNum) {
|
52
|
+
try {
|
53
|
+
await new Promise(x => setTimeout(x, this.timeout));
|
54
|
+
// Fetch logs from the network.
|
55
|
+
const logs = await this.public.getLogs({
|
56
|
+
fromBlock: this.syncedBlockNum,
|
57
|
+
toBlock: this.syncedBlockNum + this.gap,
|
58
|
+
address: contractsAddresses,
|
59
|
+
events: eventsABI,
|
60
|
+
});
|
61
|
+
await this._processLogs(logs);
|
62
|
+
this.syncedBlockNum + this.gap > this.lastBlockNum ?
|
63
|
+
this.syncedBlockNum = this.lastBlockNum :
|
64
|
+
this.syncedBlockNum += this.gap;
|
65
|
+
this.eventCount += BigInt(logs.length);
|
66
|
+
this.emitter.emit("sync", {
|
67
|
+
startBlockNum: this.startBlockNum,
|
68
|
+
endBlockNum: this.lastBlockNum,
|
69
|
+
syncedBlockNum: this.syncedBlockNum,
|
70
|
+
eventCount: this.eventCount
|
71
|
+
});
|
72
|
+
}
|
73
|
+
catch (e) {
|
74
|
+
const error = e;
|
75
|
+
if (error.name === "LimitExceededRpcError") {
|
76
|
+
this.gap = this.gap / 2n;
|
77
|
+
this.emitter.emit("syncRateLimitExeeded", this.gap);
|
78
|
+
continue;
|
79
|
+
}
|
80
|
+
throw error;
|
81
|
+
}
|
82
|
+
}
|
83
|
+
stopInitialWatcher();
|
84
|
+
}
|
85
|
+
;
|
86
|
+
on(eventName, callback) {
|
87
|
+
return this.emitter.on(eventName, callback);
|
88
|
+
}
|
89
|
+
;
|
90
|
+
async start() {
|
91
|
+
await this._sync();
|
92
|
+
this.emitter.emit('ready');
|
93
|
+
return this.public.watchBlocks({
|
94
|
+
onBlock: async (block) => {
|
95
|
+
this.syncedBlockNum = block.number;
|
96
|
+
this.emitter.emit('newBlock', block.number);
|
97
|
+
const contractsAddresses = Array.from(this.watchers.values()).map(s => s.addresses).flat(1);
|
98
|
+
const eventsABI = Array.from(this.watchers.values()).map(s => s.event);
|
99
|
+
// Fetch logs from the network.
|
100
|
+
const logs = await this.public.getLogs({
|
101
|
+
blockHash: block.hash,
|
102
|
+
address: contractsAddresses,
|
103
|
+
events: eventsABI,
|
104
|
+
});
|
105
|
+
await this._processLogs(logs);
|
106
|
+
}
|
107
|
+
});
|
108
|
+
}
|
109
|
+
async createWatcher(config) {
|
110
|
+
const watcher = new Watcher_1.Watcher(this, config);
|
111
|
+
await watcher.connect();
|
112
|
+
this.watchers.set(config.dbID, watcher);
|
113
|
+
return watcher;
|
114
|
+
}
|
115
|
+
;
|
116
|
+
}
|
117
|
+
exports.StateSync = StateSync;
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { AbiEvent, Address } from "viem";
|
2
|
+
import { IWatcherEvents, Log } from "../types/Watcher";
|
3
|
+
import { IAbstractLevel, IWatcherConfig, WatcherSchema } from "../types/Watcher";
|
4
|
+
import { StateSync } from "./Client";
|
5
|
+
import { EventSignature } from "abitype/dist/types/human-readable/types/signatures";
|
6
|
+
import { EventEmitter } from "events";
|
7
|
+
export declare class Watcher<Signature extends EventSignature> {
|
8
|
+
protected client: StateSync;
|
9
|
+
protected config: IWatcherConfig<Signature>;
|
10
|
+
protected id: string;
|
11
|
+
event: AbiEvent;
|
12
|
+
addresses: Address[];
|
13
|
+
lastSyncedBlockNumber: bigint;
|
14
|
+
protected emitter: EventEmitter;
|
15
|
+
db: IAbstractLevel<string, WatcherSchema>;
|
16
|
+
constructor(client: StateSync, config: IWatcherConfig<Signature>);
|
17
|
+
protected _updateEnv(): Promise<void>;
|
18
|
+
on<T extends keyof IWatcherEvents>(eventName: T, callback: IWatcherEvents[T]): EventEmitter;
|
19
|
+
setSyncedBlockNumber(blockNumber: bigint): Promise<void>;
|
20
|
+
connect(): Promise<void>;
|
21
|
+
onLog(log: Log<any>): Promise<void>;
|
22
|
+
/**
|
23
|
+
* onLogs is optimized to not call mutiple times the db for the same contract.
|
24
|
+
* Instead it will calculate the state in memory and save the final result in the db.
|
25
|
+
*/
|
26
|
+
onLogs(logs: Log<any>[]): Promise<void>;
|
27
|
+
}
|
@@ -0,0 +1,89 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.Watcher = void 0;
|
4
|
+
const viem_1 = require("viem");
|
5
|
+
const events_1 = require("events");
|
6
|
+
class Watcher {
|
7
|
+
constructor(client, config) {
|
8
|
+
this.client = client;
|
9
|
+
this.config = config;
|
10
|
+
this.db = new this.client.level(client.levelPath + `/${config.dbID}`.replace('//', "/"), { valueEncoding: "json" });
|
11
|
+
this.id = config.dbID;
|
12
|
+
this.event = (0, viem_1.parseAbiItem)(config.event);
|
13
|
+
this.addresses = config.addresses.map(add => (0, viem_1.checksumAddress)(add));
|
14
|
+
this.lastSyncedBlockNumber = 0n;
|
15
|
+
this.emitter = new events_1.EventEmitter();
|
16
|
+
}
|
17
|
+
;
|
18
|
+
// save some env variables in the db
|
19
|
+
async _updateEnv() {
|
20
|
+
const env = {
|
21
|
+
lastSyncedBlockNumber: this.lastSyncedBlockNumber.toString()
|
22
|
+
};
|
23
|
+
await this.db.put("ENV", env);
|
24
|
+
}
|
25
|
+
;
|
26
|
+
on(eventName, callback) {
|
27
|
+
return this.emitter.on(eventName, callback);
|
28
|
+
}
|
29
|
+
;
|
30
|
+
async setSyncedBlockNumber(blockNumber) {
|
31
|
+
this.lastSyncedBlockNumber = blockNumber;
|
32
|
+
await this._updateEnv();
|
33
|
+
}
|
34
|
+
;
|
35
|
+
async connect() {
|
36
|
+
await this.db.open();
|
37
|
+
const env = await this.db.get("ENV").catch(e => undefined);
|
38
|
+
this.lastSyncedBlockNumber = env?.lastSyncedBlockNumber ? BigInt(env.lastSyncedBlockNumber) : 0n;
|
39
|
+
}
|
40
|
+
;
|
41
|
+
async onLog(log) {
|
42
|
+
const oldData = await this.db.get((0, viem_1.checksumAddress)(log.address));
|
43
|
+
const newData = this.config.onLog(log, oldData);
|
44
|
+
this.lastSyncedBlockNumber = log.blockNumber;
|
45
|
+
await this.db.put(log.address, newData);
|
46
|
+
await this._updateEnv();
|
47
|
+
this.emitter.emit("change", {
|
48
|
+
id: log.address,
|
49
|
+
state: newData
|
50
|
+
});
|
51
|
+
}
|
52
|
+
;
|
53
|
+
/**
|
54
|
+
* onLogs is optimized to not call mutiple times the db for the same contract.
|
55
|
+
* Instead it will calculate the state in memory and save the final result in the db.
|
56
|
+
*/
|
57
|
+
async onLogs(logs) {
|
58
|
+
if (logs.length === 0)
|
59
|
+
return;
|
60
|
+
const addresses = logs.map((l) => (0, viem_1.checksumAddress)(l.address));
|
61
|
+
const oldData = await this.db.getMany(addresses);
|
62
|
+
// generate Watchers
|
63
|
+
const newDatas = new Map();
|
64
|
+
for (const index in addresses) {
|
65
|
+
const watcher = oldData[index];
|
66
|
+
const log = logs[index];
|
67
|
+
const identifier = this.config.extractIdentifier ? this.config.extractIdentifier(log) : addresses[index];
|
68
|
+
const newData = this.config.onLog(log, watcher);
|
69
|
+
newDatas.set(identifier, newData);
|
70
|
+
this.emitter.emit("change", {
|
71
|
+
id: identifier,
|
72
|
+
state: newData
|
73
|
+
});
|
74
|
+
}
|
75
|
+
;
|
76
|
+
// save results
|
77
|
+
const arr = Array.from(newDatas.entries());
|
78
|
+
const payload = arr.map(([address, newData]) => ({
|
79
|
+
type: "put",
|
80
|
+
key: address,
|
81
|
+
value: newData
|
82
|
+
}));
|
83
|
+
await this.db.batch(payload);
|
84
|
+
await this._updateEnv();
|
85
|
+
}
|
86
|
+
;
|
87
|
+
}
|
88
|
+
exports.Watcher = Watcher;
|
89
|
+
;
|
package/index.d.ts
ADDED
package/index.js
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
__exportStar(require("./classes/Client"), exports);
|
18
|
+
__exportStar(require("./classes/Watcher"), exports);
|
19
|
+
__exportStar(require("./types/Client"), exports);
|
20
|
+
__exportStar(require("./types/Watcher"), exports);
|
package/package.json
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
{
|
2
|
+
"dependencies": {
|
3
|
+
"@types/events": "^3.0.3",
|
4
|
+
"abitype": "^1.0.8",
|
5
|
+
"abstract-level": "^2.0.2",
|
6
|
+
"events": "^3.3.0",
|
7
|
+
"level": "^9.0.0",
|
8
|
+
"path": "^0.12.7",
|
9
|
+
"viem": "^2.21.58"
|
10
|
+
},
|
11
|
+
"name": "@lunarislab/state-sync",
|
12
|
+
"version": "1.0.1",
|
13
|
+
"main": "index.js",
|
14
|
+
"scripts": {
|
15
|
+
"test": "ts-node ./test.ts",
|
16
|
+
"build": "tsc && cp package.json dist/ && cp README.md dist/",
|
17
|
+
"sendNpm": "cd ./dist && npm version patch && npm publish --access=public"
|
18
|
+
},
|
19
|
+
"author": "",
|
20
|
+
"license": "ISC",
|
21
|
+
"description": "",
|
22
|
+
"devDependencies": {
|
23
|
+
"typescript": "^5.7.3"
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { PublicClient, WalletClient } from "viem";
|
2
|
+
import { LevelDBConstructor } from "./Watcher";
|
3
|
+
export interface IClientConfig {
|
4
|
+
public: PublicClient;
|
5
|
+
wallet: WalletClient;
|
6
|
+
level: LevelDBConstructor;
|
7
|
+
levelPath?: string;
|
8
|
+
timeout?: number;
|
9
|
+
}
|
10
|
+
export interface SyncParams {
|
11
|
+
startBlockNum: bigint;
|
12
|
+
endBlockNum: bigint;
|
13
|
+
syncedBlockNum: bigint;
|
14
|
+
eventCount: bigint;
|
15
|
+
}
|
16
|
+
export interface IStateSyncEvents {
|
17
|
+
sync: (params: SyncParams) => void;
|
18
|
+
ready: () => void;
|
19
|
+
newBlock: (blockNumber: bigint) => void;
|
20
|
+
syncRateLimitExceeded: (newBlockRange: number) => void;
|
21
|
+
}
|
package/types/Client.js
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
import { AbstractBatchOperation, AbstractBatchOptions, AbstractChainedBatch, AbstractIterator, AbstractIteratorOptions, AbstractKeyIterator, AbstractKeyIteratorOptions, AbstractOpenOptions, AbstractValueIterator, AbstractValueIteratorOptions } from "abstract-level";
|
2
|
+
import { AbiEvent, Address, Log as viemLog } from "viem";
|
3
|
+
import { ParseAbiItem, AbiParametersToPrimitiveTypes, AbiParameter } from 'abitype';
|
4
|
+
import { EventSignature } from "abitype/dist/types/human-readable/types/signatures";
|
5
|
+
/**
|
6
|
+
* Convert the signature to ABI type with `ParseAbiItem` and extract the inputs as `AbiParameter[]`.
|
7
|
+
* So the returned type can be used in `AbiParametersToPrimitiveTypes`.
|
8
|
+
*/
|
9
|
+
export type EventAbiInputs<signature extends EventSignature> = ParseAbiItem<signature> extends {
|
10
|
+
inputs: infer Inputs;
|
11
|
+
} ? Inputs extends readonly AbiParameter[] ? Inputs : never : never;
|
12
|
+
/**
|
13
|
+
* Not necessary but more readable, it just wrap the `AbiParametersToPrimitiveTypes` with the previous type `EventAbiInputs`.
|
14
|
+
*/
|
15
|
+
export type EventArgsTypes<signature extends EventSignature> = AbiParametersToPrimitiveTypes<EventAbiInputs<signature>>;
|
16
|
+
/**
|
17
|
+
* Check if all the keys have a name. To decide if final type is object or array.
|
18
|
+
*/
|
19
|
+
type HasAllNames<Inputs extends {
|
20
|
+
name: string;
|
21
|
+
}[]> = undefined extends Inputs[number]['name'] ? false : true;
|
22
|
+
/**
|
23
|
+
* Create the object using both EventAbiInputs for keys and the converted types for values.
|
24
|
+
*/
|
25
|
+
export type EventArgs<signature extends EventSignature> = HasAllNames<EventAbiInputs<signature>> extends true ? {
|
26
|
+
[K in EventAbiInputs<signature>[number]['name']]: EventArgsTypes<signature>[number];
|
27
|
+
} : EventArgsTypes<signature>;
|
28
|
+
export type Log<signature extends EventSignature> = viemLog & {
|
29
|
+
args: EventArgs<signature>;
|
30
|
+
};
|
31
|
+
export interface ISimplifiedWatcher {
|
32
|
+
db: IAbstractLevel<string, WatcherSchema>;
|
33
|
+
event: AbiEvent;
|
34
|
+
addresses: Address[];
|
35
|
+
lastSyncedBlockNumber: bigint;
|
36
|
+
on: <T extends keyof IWatcherEvents>(eventName: T, callback: IWatcherEvents[T]) => void;
|
37
|
+
}
|
38
|
+
export interface IWatcherEvents {
|
39
|
+
change: (data: {
|
40
|
+
id: string;
|
41
|
+
state: any;
|
42
|
+
}) => void;
|
43
|
+
}
|
44
|
+
export type WatcherSchema = {
|
45
|
+
[key: string]: number | boolean | string;
|
46
|
+
};
|
47
|
+
export interface IWatcherConfig<signature extends EventSignature> {
|
48
|
+
dbID: string;
|
49
|
+
event: signature;
|
50
|
+
extractIdentifier?: (event: Log<signature>) => string;
|
51
|
+
onLog: (event: Log<signature>, oldWatcher?: WatcherSchema) => WatcherSchema;
|
52
|
+
addresses: Address[];
|
53
|
+
}
|
54
|
+
export interface IDBEnvironment {
|
55
|
+
lastSyncedBlockNumber?: string;
|
56
|
+
}
|
57
|
+
/**
|
58
|
+
* For more modularity, LevelDB instance is injected by user, so we need to provide a generic type for LevelDB.
|
59
|
+
* Every LevelDB implementation must implement this (minimized) interface to avoid errors.
|
60
|
+
*/
|
61
|
+
export interface LevelDBConstructor<K = any, V = any> {
|
62
|
+
new (path: string, options?: any): IAbstractLevel<K, V>;
|
63
|
+
}
|
64
|
+
export declare class IAbstractLevel<KDefault = string, VDefault = string> {
|
65
|
+
/**
|
66
|
+
* Open the database.
|
67
|
+
*/
|
68
|
+
open(): Promise<void>;
|
69
|
+
open(options: AbstractOpenOptions): Promise<void>;
|
70
|
+
/**
|
71
|
+
* Get a value from the database by {@link key}.
|
72
|
+
*/
|
73
|
+
get(key: KDefault): Promise<VDefault>;
|
74
|
+
get(key: KDefault, callback: (err: any, value: VDefault) => void): Promise<VDefault>;
|
75
|
+
/**
|
76
|
+
* Get multiple values from the database by an array of {@link keys}.
|
77
|
+
*/
|
78
|
+
getMany(keys: KDefault[]): Promise<VDefault[]>;
|
79
|
+
/**
|
80
|
+
* Add a new entry or overwrite an existing entry.
|
81
|
+
*/
|
82
|
+
put(key: KDefault, value: VDefault): Promise<void>;
|
83
|
+
/**
|
84
|
+
* Delete an entry by {@link key}.
|
85
|
+
*/
|
86
|
+
del(key: KDefault): Promise<void>;
|
87
|
+
/**
|
88
|
+
* Perform multiple _put_ and/or _del_ operations in bulk.
|
89
|
+
*/
|
90
|
+
batch(operations: Array<AbstractBatchOperation<typeof this, KDefault, VDefault>>): Promise<void>;
|
91
|
+
batch<K = KDefault, V = VDefault>(operations: Array<AbstractBatchOperation<typeof this, K, V>>, options: AbstractBatchOptions<K, V>): Promise<void>;
|
92
|
+
batch(): AbstractChainedBatch<typeof this, KDefault, VDefault>;
|
93
|
+
/**
|
94
|
+
* Create an iterator. For example:
|
95
|
+
*
|
96
|
+
* ```js
|
97
|
+
* for await (const [key, value] of db.iterator({ gte: 'a' })) {
|
98
|
+
* console.log([key, value])
|
99
|
+
* }
|
100
|
+
* ```
|
101
|
+
*/
|
102
|
+
iterator(): AbstractIterator<typeof this, KDefault, VDefault>;
|
103
|
+
iterator<K = KDefault, V = VDefault>(options: AbstractIteratorOptions<K, V>): AbstractIterator<typeof this, K, V>;
|
104
|
+
/**
|
105
|
+
* Create a key iterator. For example:
|
106
|
+
*
|
107
|
+
* ```js
|
108
|
+
* for await (const key of db.keys({ gte: 'a' })) {
|
109
|
+
* console.log(key)
|
110
|
+
* }
|
111
|
+
* ```
|
112
|
+
*/
|
113
|
+
keys(): AbstractKeyIterator<typeof this, KDefault>;
|
114
|
+
keys<K = KDefault>(options: AbstractKeyIteratorOptions<K>): AbstractKeyIterator<typeof this, K>;
|
115
|
+
/**
|
116
|
+
* Create a value iterator. For example:
|
117
|
+
*
|
118
|
+
* ```js
|
119
|
+
* for await (const value of db.values({ gte: 'a' })) {
|
120
|
+
* console.log(value)
|
121
|
+
* }
|
122
|
+
* ```
|
123
|
+
*/
|
124
|
+
values(): AbstractValueIterator<typeof this, KDefault, VDefault>;
|
125
|
+
values<K = KDefault, V = VDefault>(options: AbstractValueIteratorOptions<K, V>): AbstractValueIterator<typeof this, K, V>;
|
126
|
+
/**
|
127
|
+
* Delete all entries or a range.
|
128
|
+
*/
|
129
|
+
clear(): Promise<void>;
|
130
|
+
}
|
131
|
+
export {};
|