@permissionless-technologies/upp-sdk 0.5.3 → 0.5.5
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/dist/chunk-ABVALIIG.js +152 -0
- package/dist/chunk-ABVALIIG.js.map +1 -0
- package/dist/chunk-ARH2SJM3.cjs +155 -0
- package/dist/chunk-ARH2SJM3.cjs.map +1 -0
- package/dist/{chunk-6DCMXFSQ.cjs → chunk-DD2RTRPE.cjs} +217 -4
- package/dist/chunk-DD2RTRPE.cjs.map +1 -0
- package/dist/{chunk-O2SKZZAP.cjs → chunk-KV2QFPSJ.cjs} +3 -3
- package/dist/{chunk-O2SKZZAP.cjs.map → chunk-KV2QFPSJ.cjs.map} +1 -1
- package/dist/{chunk-MVSBQMRA.js → chunk-M6O7HMN7.js} +212 -4
- package/dist/chunk-M6O7HMN7.js.map +1 -0
- package/dist/{chunk-DD4NT4D7.js → chunk-MEFCUBQC.js} +3 -3
- package/dist/{chunk-DD4NT4D7.js.map → chunk-MEFCUBQC.js.map} +1 -1
- package/dist/core/index.cjs +14 -14
- package/dist/core/index.js +4 -4
- package/dist/index.cjs +175 -175
- package/dist/index.js +6 -6
- package/dist/indexer/index.cjs +25 -25
- package/dist/indexer/index.d.cts +6 -0
- package/dist/indexer/index.d.ts +6 -0
- package/dist/indexer/index.js +2 -2
- package/dist/react/index.cjs +12 -9
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +12 -9
- package/dist/react/index.js.map +1 -1
- package/dist/{transfer-CKA4PU2C.js → transfer-BVZAMEJH.js} +4 -4
- package/dist/{transfer-CKA4PU2C.js.map → transfer-BVZAMEJH.js.map} +1 -1
- package/dist/{transfer-QFTVCREE.cjs → transfer-ZD76R7XF.cjs} +10 -10
- package/dist/{transfer-QFTVCREE.cjs.map → transfer-ZD76R7XF.cjs.map} +1 -1
- package/package.json +1 -1
- package/dist/chunk-6DCMXFSQ.cjs.map +0 -1
- package/dist/chunk-ERQE57IA.cjs +0 -404
- package/dist/chunk-ERQE57IA.cjs.map +0 -1
- package/dist/chunk-MVSBQMRA.js.map +0 -1
- package/dist/chunk-XV72HNHN.js +0 -399
- package/dist/chunk-XV72HNHN.js.map +0 -1
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// src/indexer/storage/indexedDB.ts
|
|
2
|
+
var DB_NAME = "upp-indexer";
|
|
3
|
+
var DB_VERSION = 1;
|
|
4
|
+
var STORE_NAME = "keyval";
|
|
5
|
+
var IndexedDBAdapter = class {
|
|
6
|
+
dbPromise = null;
|
|
7
|
+
prefix;
|
|
8
|
+
constructor(prefix = "") {
|
|
9
|
+
this.prefix = prefix;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Check if IndexedDB is available
|
|
13
|
+
*/
|
|
14
|
+
isAvailable() {
|
|
15
|
+
if (typeof window === "undefined") return false;
|
|
16
|
+
return "indexedDB" in window;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get the database instance
|
|
20
|
+
*/
|
|
21
|
+
async getDB() {
|
|
22
|
+
if (!this.isAvailable()) {
|
|
23
|
+
throw new Error("IndexedDB is not available");
|
|
24
|
+
}
|
|
25
|
+
if (this.dbPromise) {
|
|
26
|
+
return this.dbPromise;
|
|
27
|
+
}
|
|
28
|
+
this.dbPromise = new Promise((resolve, reject) => {
|
|
29
|
+
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
|
30
|
+
request.onerror = () => {
|
|
31
|
+
reject(new Error(`Failed to open IndexedDB: ${request.error?.message}`));
|
|
32
|
+
};
|
|
33
|
+
request.onsuccess = () => {
|
|
34
|
+
resolve(request.result);
|
|
35
|
+
};
|
|
36
|
+
request.onupgradeneeded = (event) => {
|
|
37
|
+
const db = event.target.result;
|
|
38
|
+
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
39
|
+
db.createObjectStore(STORE_NAME);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
return this.dbPromise;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get the full key with prefix
|
|
47
|
+
*/
|
|
48
|
+
getKey(key) {
|
|
49
|
+
return this.prefix ? `${this.prefix}:${key}` : key;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get a value by key
|
|
53
|
+
*/
|
|
54
|
+
async get(key) {
|
|
55
|
+
const db = await this.getDB();
|
|
56
|
+
const fullKey = this.getKey(key);
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
const transaction = db.transaction(STORE_NAME, "readonly");
|
|
59
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
60
|
+
const request = store.get(fullKey);
|
|
61
|
+
request.onerror = () => {
|
|
62
|
+
reject(new Error(`Failed to get key "${fullKey}": ${request.error?.message}`));
|
|
63
|
+
};
|
|
64
|
+
request.onsuccess = () => {
|
|
65
|
+
resolve(request.result ?? null);
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Set a value
|
|
71
|
+
*/
|
|
72
|
+
async set(key, value) {
|
|
73
|
+
const db = await this.getDB();
|
|
74
|
+
const fullKey = this.getKey(key);
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
|
+
const transaction = db.transaction(STORE_NAME, "readwrite");
|
|
77
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
78
|
+
const request = store.put(value, fullKey);
|
|
79
|
+
request.onerror = () => {
|
|
80
|
+
reject(new Error(`Failed to set key "${fullKey}": ${request.error?.message}`));
|
|
81
|
+
};
|
|
82
|
+
request.onsuccess = () => {
|
|
83
|
+
resolve();
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Delete a value
|
|
89
|
+
*/
|
|
90
|
+
async delete(key) {
|
|
91
|
+
const db = await this.getDB();
|
|
92
|
+
const fullKey = this.getKey(key);
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
const transaction = db.transaction(STORE_NAME, "readwrite");
|
|
95
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
96
|
+
const request = store.delete(fullKey);
|
|
97
|
+
request.onerror = () => {
|
|
98
|
+
reject(new Error(`Failed to delete key "${fullKey}": ${request.error?.message}`));
|
|
99
|
+
};
|
|
100
|
+
request.onsuccess = () => {
|
|
101
|
+
resolve();
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Clear all data with this prefix
|
|
107
|
+
*/
|
|
108
|
+
async clear() {
|
|
109
|
+
const db = await this.getDB();
|
|
110
|
+
return new Promise((resolve, reject) => {
|
|
111
|
+
const transaction = db.transaction(STORE_NAME, "readwrite");
|
|
112
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
113
|
+
if (!this.prefix) {
|
|
114
|
+
const request = store.clear();
|
|
115
|
+
request.onerror = () => reject(new Error(`Failed to clear: ${request.error?.message}`));
|
|
116
|
+
request.onsuccess = () => resolve();
|
|
117
|
+
} else {
|
|
118
|
+
const request = store.openCursor();
|
|
119
|
+
const keysToDelete = [];
|
|
120
|
+
request.onerror = () => reject(new Error(`Failed to iterate: ${request.error?.message}`));
|
|
121
|
+
request.onsuccess = (event) => {
|
|
122
|
+
const cursor = event.target.result;
|
|
123
|
+
if (cursor) {
|
|
124
|
+
const key = cursor.key;
|
|
125
|
+
if (typeof key === "string" && key.startsWith(`${this.prefix}:`)) {
|
|
126
|
+
keysToDelete.push(key);
|
|
127
|
+
}
|
|
128
|
+
cursor.continue();
|
|
129
|
+
} else {
|
|
130
|
+
Promise.all(
|
|
131
|
+
keysToDelete.map(
|
|
132
|
+
(k) => new Promise((res, rej) => {
|
|
133
|
+
const deleteReq = store.delete(k);
|
|
134
|
+
deleteReq.onerror = () => rej(deleteReq.error);
|
|
135
|
+
deleteReq.onsuccess = () => res();
|
|
136
|
+
})
|
|
137
|
+
)
|
|
138
|
+
).then(() => resolve()).catch(reject);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
function createIndexedDBAdapter(prefix = "") {
|
|
146
|
+
return new IndexedDBAdapter(prefix);
|
|
147
|
+
}
|
|
148
|
+
var indexedDBAdapter = createIndexedDBAdapter();
|
|
149
|
+
|
|
150
|
+
export { createIndexedDBAdapter, indexedDBAdapter };
|
|
151
|
+
//# sourceMappingURL=chunk-ABVALIIG.js.map
|
|
152
|
+
//# sourceMappingURL=chunk-ABVALIIG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/indexer/storage/indexedDB.ts"],"names":[],"mappings":"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","file":"chunk-ABVALIIG.js","sourcesContent":["/**\n * IndexedDB Storage Adapter\n *\n * Provides persistent storage using IndexedDB for browser environments.\n * This is the default and recommended storage adapter for production use.\n *\n * Benefits:\n * - Large capacity (no 5MB limit like localStorage)\n * - Async API (non-blocking)\n * - Supports storing large objects like Merkle trees\n * - Transactional (data integrity)\n */\n\nimport type { StorageAdapter } from '../types.js'\n\nconst DB_NAME = 'upp-indexer'\nconst DB_VERSION = 1\nconst STORE_NAME = 'keyval'\n\n/**\n * IndexedDB storage adapter\n */\nclass IndexedDBAdapter implements StorageAdapter {\n private dbPromise: Promise<IDBDatabase> | null = null\n private prefix: string\n\n constructor(prefix: string = '') {\n this.prefix = prefix\n }\n\n /**\n * Check if IndexedDB is available\n */\n isAvailable(): boolean {\n if (typeof window === 'undefined') return false\n return 'indexedDB' in window\n }\n\n /**\n * Get the database instance\n */\n private async getDB(): Promise<IDBDatabase> {\n if (!this.isAvailable()) {\n throw new Error('IndexedDB is not available')\n }\n\n if (this.dbPromise) {\n return this.dbPromise\n }\n\n this.dbPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION)\n\n request.onerror = () => {\n reject(new Error(`Failed to open IndexedDB: ${request.error?.message}`))\n }\n\n request.onsuccess = () => {\n resolve(request.result)\n }\n\n request.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result\n\n // Create object store if it doesn't exist\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME)\n }\n }\n })\n\n return this.dbPromise\n }\n\n /**\n * Get the full key with prefix\n */\n private getKey(key: string): string {\n return this.prefix ? `${this.prefix}:${key}` : key\n }\n\n /**\n * Get a value by key\n */\n async get<T>(key: string): Promise<T | null> {\n const db = await this.getDB()\n const fullKey = this.getKey(key)\n\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(STORE_NAME, 'readonly')\n const store = transaction.objectStore(STORE_NAME)\n const request = store.get(fullKey)\n\n request.onerror = () => {\n reject(new Error(`Failed to get key \"${fullKey}\": ${request.error?.message}`))\n }\n\n request.onsuccess = () => {\n resolve(request.result ?? null)\n }\n })\n }\n\n /**\n * Set a value\n */\n async set<T>(key: string, value: T): Promise<void> {\n const db = await this.getDB()\n const fullKey = this.getKey(key)\n\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(STORE_NAME, 'readwrite')\n const store = transaction.objectStore(STORE_NAME)\n const request = store.put(value, fullKey)\n\n request.onerror = () => {\n reject(new Error(`Failed to set key \"${fullKey}\": ${request.error?.message}`))\n }\n\n request.onsuccess = () => {\n resolve()\n }\n })\n }\n\n /**\n * Delete a value\n */\n async delete(key: string): Promise<void> {\n const db = await this.getDB()\n const fullKey = this.getKey(key)\n\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(STORE_NAME, 'readwrite')\n const store = transaction.objectStore(STORE_NAME)\n const request = store.delete(fullKey)\n\n request.onerror = () => {\n reject(new Error(`Failed to delete key \"${fullKey}\": ${request.error?.message}`))\n }\n\n request.onsuccess = () => {\n resolve()\n }\n })\n }\n\n /**\n * Clear all data with this prefix\n */\n async clear(): Promise<void> {\n const db = await this.getDB()\n\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(STORE_NAME, 'readwrite')\n const store = transaction.objectStore(STORE_NAME)\n\n if (!this.prefix) {\n // Clear all if no prefix\n const request = store.clear()\n request.onerror = () => reject(new Error(`Failed to clear: ${request.error?.message}`))\n request.onsuccess = () => resolve()\n } else {\n // Only clear keys with this prefix\n const request = store.openCursor()\n const keysToDelete: IDBValidKey[] = []\n\n request.onerror = () => reject(new Error(`Failed to iterate: ${request.error?.message}`))\n\n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result\n if (cursor) {\n const key = cursor.key\n if (typeof key === 'string' && key.startsWith(`${this.prefix}:`)) {\n keysToDelete.push(key)\n }\n cursor.continue()\n } else {\n // Delete all matching keys\n Promise.all(\n keysToDelete.map(\n (k) =>\n new Promise<void>((res, rej) => {\n const deleteReq = store.delete(k)\n deleteReq.onerror = () => rej(deleteReq.error)\n deleteReq.onsuccess = () => res()\n })\n )\n )\n .then(() => resolve())\n .catch(reject)\n }\n }\n }\n })\n }\n}\n\n/**\n * Create an IndexedDB storage adapter\n *\n * @param prefix - Optional prefix for keys (useful for multi-account)\n * @returns StorageAdapter instance\n *\n * @example\n * ```ts\n * const storage = createIndexedDBAdapter('account_0x123')\n * await storage.set('notes', myNotes)\n * const notes = await storage.get('notes')\n * ```\n */\nexport function createIndexedDBAdapter(prefix: string = ''): StorageAdapter {\n return new IndexedDBAdapter(prefix)\n}\n\n/**\n * Default IndexedDB adapter instance (no prefix)\n */\nexport const indexedDBAdapter = createIndexedDBAdapter()\n"]}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/indexer/storage/indexedDB.ts
|
|
4
|
+
var DB_NAME = "upp-indexer";
|
|
5
|
+
var DB_VERSION = 1;
|
|
6
|
+
var STORE_NAME = "keyval";
|
|
7
|
+
var IndexedDBAdapter = class {
|
|
8
|
+
dbPromise = null;
|
|
9
|
+
prefix;
|
|
10
|
+
constructor(prefix = "") {
|
|
11
|
+
this.prefix = prefix;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Check if IndexedDB is available
|
|
15
|
+
*/
|
|
16
|
+
isAvailable() {
|
|
17
|
+
if (typeof window === "undefined") return false;
|
|
18
|
+
return "indexedDB" in window;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the database instance
|
|
22
|
+
*/
|
|
23
|
+
async getDB() {
|
|
24
|
+
if (!this.isAvailable()) {
|
|
25
|
+
throw new Error("IndexedDB is not available");
|
|
26
|
+
}
|
|
27
|
+
if (this.dbPromise) {
|
|
28
|
+
return this.dbPromise;
|
|
29
|
+
}
|
|
30
|
+
this.dbPromise = new Promise((resolve, reject) => {
|
|
31
|
+
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
|
32
|
+
request.onerror = () => {
|
|
33
|
+
reject(new Error(`Failed to open IndexedDB: ${request.error?.message}`));
|
|
34
|
+
};
|
|
35
|
+
request.onsuccess = () => {
|
|
36
|
+
resolve(request.result);
|
|
37
|
+
};
|
|
38
|
+
request.onupgradeneeded = (event) => {
|
|
39
|
+
const db = event.target.result;
|
|
40
|
+
if (!db.objectStoreNames.contains(STORE_NAME)) {
|
|
41
|
+
db.createObjectStore(STORE_NAME);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
return this.dbPromise;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the full key with prefix
|
|
49
|
+
*/
|
|
50
|
+
getKey(key) {
|
|
51
|
+
return this.prefix ? `${this.prefix}:${key}` : key;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get a value by key
|
|
55
|
+
*/
|
|
56
|
+
async get(key) {
|
|
57
|
+
const db = await this.getDB();
|
|
58
|
+
const fullKey = this.getKey(key);
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
const transaction = db.transaction(STORE_NAME, "readonly");
|
|
61
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
62
|
+
const request = store.get(fullKey);
|
|
63
|
+
request.onerror = () => {
|
|
64
|
+
reject(new Error(`Failed to get key "${fullKey}": ${request.error?.message}`));
|
|
65
|
+
};
|
|
66
|
+
request.onsuccess = () => {
|
|
67
|
+
resolve(request.result ?? null);
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Set a value
|
|
73
|
+
*/
|
|
74
|
+
async set(key, value) {
|
|
75
|
+
const db = await this.getDB();
|
|
76
|
+
const fullKey = this.getKey(key);
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
const transaction = db.transaction(STORE_NAME, "readwrite");
|
|
79
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
80
|
+
const request = store.put(value, fullKey);
|
|
81
|
+
request.onerror = () => {
|
|
82
|
+
reject(new Error(`Failed to set key "${fullKey}": ${request.error?.message}`));
|
|
83
|
+
};
|
|
84
|
+
request.onsuccess = () => {
|
|
85
|
+
resolve();
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Delete a value
|
|
91
|
+
*/
|
|
92
|
+
async delete(key) {
|
|
93
|
+
const db = await this.getDB();
|
|
94
|
+
const fullKey = this.getKey(key);
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
const transaction = db.transaction(STORE_NAME, "readwrite");
|
|
97
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
98
|
+
const request = store.delete(fullKey);
|
|
99
|
+
request.onerror = () => {
|
|
100
|
+
reject(new Error(`Failed to delete key "${fullKey}": ${request.error?.message}`));
|
|
101
|
+
};
|
|
102
|
+
request.onsuccess = () => {
|
|
103
|
+
resolve();
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Clear all data with this prefix
|
|
109
|
+
*/
|
|
110
|
+
async clear() {
|
|
111
|
+
const db = await this.getDB();
|
|
112
|
+
return new Promise((resolve, reject) => {
|
|
113
|
+
const transaction = db.transaction(STORE_NAME, "readwrite");
|
|
114
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
115
|
+
if (!this.prefix) {
|
|
116
|
+
const request = store.clear();
|
|
117
|
+
request.onerror = () => reject(new Error(`Failed to clear: ${request.error?.message}`));
|
|
118
|
+
request.onsuccess = () => resolve();
|
|
119
|
+
} else {
|
|
120
|
+
const request = store.openCursor();
|
|
121
|
+
const keysToDelete = [];
|
|
122
|
+
request.onerror = () => reject(new Error(`Failed to iterate: ${request.error?.message}`));
|
|
123
|
+
request.onsuccess = (event) => {
|
|
124
|
+
const cursor = event.target.result;
|
|
125
|
+
if (cursor) {
|
|
126
|
+
const key = cursor.key;
|
|
127
|
+
if (typeof key === "string" && key.startsWith(`${this.prefix}:`)) {
|
|
128
|
+
keysToDelete.push(key);
|
|
129
|
+
}
|
|
130
|
+
cursor.continue();
|
|
131
|
+
} else {
|
|
132
|
+
Promise.all(
|
|
133
|
+
keysToDelete.map(
|
|
134
|
+
(k) => new Promise((res, rej) => {
|
|
135
|
+
const deleteReq = store.delete(k);
|
|
136
|
+
deleteReq.onerror = () => rej(deleteReq.error);
|
|
137
|
+
deleteReq.onsuccess = () => res();
|
|
138
|
+
})
|
|
139
|
+
)
|
|
140
|
+
).then(() => resolve()).catch(reject);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
function createIndexedDBAdapter(prefix = "") {
|
|
148
|
+
return new IndexedDBAdapter(prefix);
|
|
149
|
+
}
|
|
150
|
+
var indexedDBAdapter = createIndexedDBAdapter();
|
|
151
|
+
|
|
152
|
+
exports.createIndexedDBAdapter = createIndexedDBAdapter;
|
|
153
|
+
exports.indexedDBAdapter = indexedDBAdapter;
|
|
154
|
+
//# sourceMappingURL=chunk-ARH2SJM3.cjs.map
|
|
155
|
+
//# sourceMappingURL=chunk-ARH2SJM3.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/indexer/storage/indexedDB.ts"],"names":[],"mappings":"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","file":"chunk-ARH2SJM3.cjs","sourcesContent":["/**\n * IndexedDB Storage Adapter\n *\n * Provides persistent storage using IndexedDB for browser environments.\n * This is the default and recommended storage adapter for production use.\n *\n * Benefits:\n * - Large capacity (no 5MB limit like localStorage)\n * - Async API (non-blocking)\n * - Supports storing large objects like Merkle trees\n * - Transactional (data integrity)\n */\n\nimport type { StorageAdapter } from '../types.js'\n\nconst DB_NAME = 'upp-indexer'\nconst DB_VERSION = 1\nconst STORE_NAME = 'keyval'\n\n/**\n * IndexedDB storage adapter\n */\nclass IndexedDBAdapter implements StorageAdapter {\n private dbPromise: Promise<IDBDatabase> | null = null\n private prefix: string\n\n constructor(prefix: string = '') {\n this.prefix = prefix\n }\n\n /**\n * Check if IndexedDB is available\n */\n isAvailable(): boolean {\n if (typeof window === 'undefined') return false\n return 'indexedDB' in window\n }\n\n /**\n * Get the database instance\n */\n private async getDB(): Promise<IDBDatabase> {\n if (!this.isAvailable()) {\n throw new Error('IndexedDB is not available')\n }\n\n if (this.dbPromise) {\n return this.dbPromise\n }\n\n this.dbPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(DB_NAME, DB_VERSION)\n\n request.onerror = () => {\n reject(new Error(`Failed to open IndexedDB: ${request.error?.message}`))\n }\n\n request.onsuccess = () => {\n resolve(request.result)\n }\n\n request.onupgradeneeded = (event) => {\n const db = (event.target as IDBOpenDBRequest).result\n\n // Create object store if it doesn't exist\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n db.createObjectStore(STORE_NAME)\n }\n }\n })\n\n return this.dbPromise\n }\n\n /**\n * Get the full key with prefix\n */\n private getKey(key: string): string {\n return this.prefix ? `${this.prefix}:${key}` : key\n }\n\n /**\n * Get a value by key\n */\n async get<T>(key: string): Promise<T | null> {\n const db = await this.getDB()\n const fullKey = this.getKey(key)\n\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(STORE_NAME, 'readonly')\n const store = transaction.objectStore(STORE_NAME)\n const request = store.get(fullKey)\n\n request.onerror = () => {\n reject(new Error(`Failed to get key \"${fullKey}\": ${request.error?.message}`))\n }\n\n request.onsuccess = () => {\n resolve(request.result ?? null)\n }\n })\n }\n\n /**\n * Set a value\n */\n async set<T>(key: string, value: T): Promise<void> {\n const db = await this.getDB()\n const fullKey = this.getKey(key)\n\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(STORE_NAME, 'readwrite')\n const store = transaction.objectStore(STORE_NAME)\n const request = store.put(value, fullKey)\n\n request.onerror = () => {\n reject(new Error(`Failed to set key \"${fullKey}\": ${request.error?.message}`))\n }\n\n request.onsuccess = () => {\n resolve()\n }\n })\n }\n\n /**\n * Delete a value\n */\n async delete(key: string): Promise<void> {\n const db = await this.getDB()\n const fullKey = this.getKey(key)\n\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(STORE_NAME, 'readwrite')\n const store = transaction.objectStore(STORE_NAME)\n const request = store.delete(fullKey)\n\n request.onerror = () => {\n reject(new Error(`Failed to delete key \"${fullKey}\": ${request.error?.message}`))\n }\n\n request.onsuccess = () => {\n resolve()\n }\n })\n }\n\n /**\n * Clear all data with this prefix\n */\n async clear(): Promise<void> {\n const db = await this.getDB()\n\n return new Promise((resolve, reject) => {\n const transaction = db.transaction(STORE_NAME, 'readwrite')\n const store = transaction.objectStore(STORE_NAME)\n\n if (!this.prefix) {\n // Clear all if no prefix\n const request = store.clear()\n request.onerror = () => reject(new Error(`Failed to clear: ${request.error?.message}`))\n request.onsuccess = () => resolve()\n } else {\n // Only clear keys with this prefix\n const request = store.openCursor()\n const keysToDelete: IDBValidKey[] = []\n\n request.onerror = () => reject(new Error(`Failed to iterate: ${request.error?.message}`))\n\n request.onsuccess = (event) => {\n const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result\n if (cursor) {\n const key = cursor.key\n if (typeof key === 'string' && key.startsWith(`${this.prefix}:`)) {\n keysToDelete.push(key)\n }\n cursor.continue()\n } else {\n // Delete all matching keys\n Promise.all(\n keysToDelete.map(\n (k) =>\n new Promise<void>((res, rej) => {\n const deleteReq = store.delete(k)\n deleteReq.onerror = () => rej(deleteReq.error)\n deleteReq.onsuccess = () => res()\n })\n )\n )\n .then(() => resolve())\n .catch(reject)\n }\n }\n }\n })\n }\n}\n\n/**\n * Create an IndexedDB storage adapter\n *\n * @param prefix - Optional prefix for keys (useful for multi-account)\n * @returns StorageAdapter instance\n *\n * @example\n * ```ts\n * const storage = createIndexedDBAdapter('account_0x123')\n * await storage.set('notes', myNotes)\n * const notes = await storage.get('notes')\n * ```\n */\nexport function createIndexedDBAdapter(prefix: string = ''): StorageAdapter {\n return new IndexedDBAdapter(prefix)\n}\n\n/**\n * Default IndexedDB adapter instance (no prefix)\n */\nexport const indexedDBAdapter = createIndexedDBAdapter()\n"]}
|
|
@@ -1,8 +1,216 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkARH2SJM3_cjs = require('./chunk-ARH2SJM3.cjs');
|
|
4
4
|
var viem = require('viem');
|
|
5
5
|
|
|
6
|
+
// src/indexer/storage/localStorage.ts
|
|
7
|
+
var LocalStorageAdapter = class {
|
|
8
|
+
prefix;
|
|
9
|
+
constructor(prefix = "") {
|
|
10
|
+
this.prefix = prefix;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check if localStorage is available
|
|
14
|
+
*/
|
|
15
|
+
isAvailable() {
|
|
16
|
+
if (typeof window === "undefined") return false;
|
|
17
|
+
try {
|
|
18
|
+
const test = "__storage_test__";
|
|
19
|
+
window.localStorage.setItem(test, test);
|
|
20
|
+
window.localStorage.removeItem(test);
|
|
21
|
+
return true;
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get the full key with prefix
|
|
28
|
+
*/
|
|
29
|
+
getKey(key) {
|
|
30
|
+
return this.prefix ? `upp:${this.prefix}:${key}` : `upp:${key}`;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get a value by key
|
|
34
|
+
*/
|
|
35
|
+
async get(key) {
|
|
36
|
+
if (!this.isAvailable()) {
|
|
37
|
+
throw new Error("localStorage is not available");
|
|
38
|
+
}
|
|
39
|
+
const fullKey = this.getKey(key);
|
|
40
|
+
const value = localStorage.getItem(fullKey);
|
|
41
|
+
if (value === null) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(value);
|
|
46
|
+
} catch {
|
|
47
|
+
console.warn(`Failed to parse localStorage value for key "${fullKey}"`);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Set a value
|
|
53
|
+
*/
|
|
54
|
+
async set(key, value) {
|
|
55
|
+
if (!this.isAvailable()) {
|
|
56
|
+
throw new Error("localStorage is not available");
|
|
57
|
+
}
|
|
58
|
+
const fullKey = this.getKey(key);
|
|
59
|
+
try {
|
|
60
|
+
const serialized = JSON.stringify(value);
|
|
61
|
+
localStorage.setItem(fullKey, serialized);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
if (e instanceof Error && e.name === "QuotaExceededError") {
|
|
64
|
+
throw new Error("localStorage quota exceeded. Consider using IndexedDB instead.");
|
|
65
|
+
}
|
|
66
|
+
throw e;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Delete a value
|
|
71
|
+
*/
|
|
72
|
+
async delete(key) {
|
|
73
|
+
if (!this.isAvailable()) {
|
|
74
|
+
throw new Error("localStorage is not available");
|
|
75
|
+
}
|
|
76
|
+
const fullKey = this.getKey(key);
|
|
77
|
+
localStorage.removeItem(fullKey);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Clear all data with this prefix
|
|
81
|
+
*/
|
|
82
|
+
async clear() {
|
|
83
|
+
if (!this.isAvailable()) {
|
|
84
|
+
throw new Error("localStorage is not available");
|
|
85
|
+
}
|
|
86
|
+
const prefix = this.prefix ? `upp:${this.prefix}:` : "upp:";
|
|
87
|
+
const keysToRemove = [];
|
|
88
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
89
|
+
const key = localStorage.key(i);
|
|
90
|
+
if (key && key.startsWith(prefix)) {
|
|
91
|
+
keysToRemove.push(key);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const key of keysToRemove) {
|
|
95
|
+
localStorage.removeItem(key);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
function createLocalStorageAdapter(prefix = "") {
|
|
100
|
+
return new LocalStorageAdapter(prefix);
|
|
101
|
+
}
|
|
102
|
+
var localStorageAdapter = createLocalStorageAdapter();
|
|
103
|
+
|
|
104
|
+
// src/indexer/storage/memory.ts
|
|
105
|
+
var MemoryAdapter = class {
|
|
106
|
+
store;
|
|
107
|
+
prefix;
|
|
108
|
+
constructor(prefix = "") {
|
|
109
|
+
this.store = /* @__PURE__ */ new Map();
|
|
110
|
+
this.prefix = prefix;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Always available
|
|
114
|
+
*/
|
|
115
|
+
isAvailable() {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get the full key with prefix
|
|
120
|
+
*/
|
|
121
|
+
getKey(key) {
|
|
122
|
+
return this.prefix ? `${this.prefix}:${key}` : key;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get a value by key
|
|
126
|
+
*/
|
|
127
|
+
async get(key) {
|
|
128
|
+
const fullKey = this.getKey(key);
|
|
129
|
+
const value = this.store.get(fullKey);
|
|
130
|
+
return value ?? null;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Set a value
|
|
134
|
+
*/
|
|
135
|
+
async set(key, value) {
|
|
136
|
+
const fullKey = this.getKey(key);
|
|
137
|
+
this.store.set(fullKey, structuredClone(value));
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Delete a value
|
|
141
|
+
*/
|
|
142
|
+
async delete(key) {
|
|
143
|
+
const fullKey = this.getKey(key);
|
|
144
|
+
this.store.delete(fullKey);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Clear all data with this prefix
|
|
148
|
+
*/
|
|
149
|
+
async clear() {
|
|
150
|
+
if (!this.prefix) {
|
|
151
|
+
this.store.clear();
|
|
152
|
+
} else {
|
|
153
|
+
const keysToDelete = [];
|
|
154
|
+
for (const key of this.store.keys()) {
|
|
155
|
+
if (key.startsWith(`${this.prefix}:`)) {
|
|
156
|
+
keysToDelete.push(key);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
for (const key of keysToDelete) {
|
|
160
|
+
this.store.delete(key);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get the number of stored items (for testing)
|
|
166
|
+
*/
|
|
167
|
+
size() {
|
|
168
|
+
if (!this.prefix) {
|
|
169
|
+
return this.store.size;
|
|
170
|
+
}
|
|
171
|
+
let count = 0;
|
|
172
|
+
for (const key of this.store.keys()) {
|
|
173
|
+
if (key.startsWith(`${this.prefix}:`)) {
|
|
174
|
+
count++;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return count;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Get all keys (for testing)
|
|
181
|
+
*/
|
|
182
|
+
keys() {
|
|
183
|
+
const result = [];
|
|
184
|
+
const prefixToRemove = this.prefix ? `${this.prefix}:` : "";
|
|
185
|
+
for (const key of this.store.keys()) {
|
|
186
|
+
if (!this.prefix || key.startsWith(prefixToRemove)) {
|
|
187
|
+
result.push(this.prefix ? key.slice(prefixToRemove.length) : key);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
function createMemoryAdapter(prefix = "") {
|
|
194
|
+
return new MemoryAdapter(prefix);
|
|
195
|
+
}
|
|
196
|
+
var memoryAdapter = createMemoryAdapter();
|
|
197
|
+
|
|
198
|
+
// src/indexer/storage/index.ts
|
|
199
|
+
function createAutoAdapter(prefix = "") {
|
|
200
|
+
if (typeof window !== "undefined" && "indexedDB" in window) {
|
|
201
|
+
return chunkARH2SJM3_cjs.createIndexedDBAdapter(prefix);
|
|
202
|
+
}
|
|
203
|
+
if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
|
|
204
|
+
try {
|
|
205
|
+
const test = "__storage_test__";
|
|
206
|
+
localStorage.setItem(test, test);
|
|
207
|
+
localStorage.removeItem(test);
|
|
208
|
+
return createLocalStorageAdapter(prefix);
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return createMemoryAdapter(prefix);
|
|
213
|
+
}
|
|
6
214
|
async function computeSearchTag(sdk, masterViewingSecret, masterViewingPubKey, ephemeralPubkey, debug = false) {
|
|
7
215
|
const dvk = await sdk.deriveDecryptionViewingKey(
|
|
8
216
|
masterViewingSecret,
|
|
@@ -330,7 +538,7 @@ var RpcIndexer = class {
|
|
|
330
538
|
this.batchDelayMs = config.batchDelayMs ?? BATCH_DELAY_MS;
|
|
331
539
|
this.initialFromBlock = config.fromBlock ?? 0;
|
|
332
540
|
const accountPrefix = `${config.chainId}_${config.contractAddress.slice(2, 10)}_${viem.toHex(config.spendingPubkey.x).slice(2, 12)}`;
|
|
333
|
-
this.storage = config.storage ??
|
|
541
|
+
this.storage = config.storage ?? createAutoAdapter(accountPrefix);
|
|
334
542
|
this.rateLimiter = new RateLimiter(DEFAULT_REQUESTS_PER_SECOND, DEFAULT_MAX_CONCURRENT);
|
|
335
543
|
}
|
|
336
544
|
/**
|
|
@@ -990,9 +1198,14 @@ function sleep(ms) {
|
|
|
990
1198
|
}
|
|
991
1199
|
|
|
992
1200
|
exports.computeSearchTag = computeSearchTag;
|
|
1201
|
+
exports.createAutoAdapter = createAutoAdapter;
|
|
1202
|
+
exports.createLocalStorageAdapter = createLocalStorageAdapter;
|
|
1203
|
+
exports.createMemoryAdapter = createMemoryAdapter;
|
|
1204
|
+
exports.localStorageAdapter = localStorageAdapter;
|
|
993
1205
|
exports.makeRpcIndexer = makeRpcIndexer;
|
|
994
1206
|
exports.matchesSearchTag = matchesSearchTag;
|
|
1207
|
+
exports.memoryAdapter = memoryAdapter;
|
|
995
1208
|
exports.tryDecryptNote = tryDecryptNote;
|
|
996
1209
|
exports.unpackNoteData = unpackNoteData;
|
|
997
|
-
//# sourceMappingURL=chunk-
|
|
998
|
-
//# sourceMappingURL=chunk-
|
|
1210
|
+
//# sourceMappingURL=chunk-DD2RTRPE.cjs.map
|
|
1211
|
+
//# sourceMappingURL=chunk-DD2RTRPE.cjs.map
|