@prosopo/database 0.2.41 → 0.3.2
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 +0 -0
- package/dist/cjs/databases/mongo.cjs +198 -132
- package/dist/cjs/databases/mongoMemory.cjs +20 -2
- package/dist/cjs/eventsDatabase/eventsDatabase.cjs +7 -33
- package/dist/databases/mongo.d.ts +7 -2
- package/dist/databases/mongo.d.ts.map +1 -1
- package/dist/databases/mongo.js +140 -59
- package/dist/databases/mongo.js.map +1 -1
- package/dist/databases/mongoMemory.d.ts +4 -0
- package/dist/databases/mongoMemory.d.ts.map +1 -1
- package/dist/databases/mongoMemory.js +21 -2
- package/dist/databases/mongoMemory.js.map +1 -1
- package/dist/eventsDatabase/eventsDatabase.d.ts +1 -1
- package/dist/eventsDatabase/eventsDatabase.d.ts.map +1 -1
- package/dist/eventsDatabase/eventsDatabase.js +8 -37
- package/dist/eventsDatabase/eventsDatabase.js.map +1 -1
- package/package.json +7 -7
- package/typedoc.config.js +19 -0
- package/vite.cjs.config.ts +13 -0
package/README.md
ADDED
|
File without changes
|
|
@@ -28,73 +28,82 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
28
28
|
this.logger = logger;
|
|
29
29
|
return this;
|
|
30
30
|
}
|
|
31
|
+
getTables() {
|
|
32
|
+
if (!this.tables) {
|
|
33
|
+
throw new common.ProsopoDBError("DATABASE.TABLES_UNDEFINED", {
|
|
34
|
+
context: { failedFuncName: this.getTables.name },
|
|
35
|
+
logger: this.logger
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return this.tables;
|
|
39
|
+
}
|
|
40
|
+
getConnection() {
|
|
41
|
+
if (!this.connection) {
|
|
42
|
+
throw new common.ProsopoDBError("DATABASE.CONNECTION_UNDEFINED", {
|
|
43
|
+
context: { failedFuncName: this.getConnection.name },
|
|
44
|
+
logger: this.logger
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return this.connection;
|
|
48
|
+
}
|
|
31
49
|
/**
|
|
32
50
|
* @description Connect to the database and set the various tables
|
|
33
51
|
*/
|
|
34
52
|
async connect() {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
53
|
+
this.logger.info(`Mongo url: ${this.url.replace(/\w+:\w+/, "<Credentials>")}`);
|
|
54
|
+
this.connection = await new Promise((resolve, reject) => {
|
|
55
|
+
const connection = mongoose.createConnection(this.url, {
|
|
56
|
+
dbName: this.dbname,
|
|
57
|
+
serverApi: mongodb.ServerApiVersion.v1
|
|
58
|
+
});
|
|
59
|
+
connection.on("open", () => {
|
|
60
|
+
this.logger.info(`Database connection to ${this.url} opened`);
|
|
61
|
+
resolve(connection);
|
|
62
|
+
});
|
|
63
|
+
connection.on("error", (err) => {
|
|
64
|
+
this.logger.error(`Database error: ${err}`);
|
|
65
|
+
reject(err);
|
|
66
|
+
});
|
|
67
|
+
connection.on("connected", () => {
|
|
68
|
+
this.logger.info(`Database connected to ${this.url}`);
|
|
69
|
+
});
|
|
70
|
+
connection.on("disconnected", () => {
|
|
71
|
+
this.logger.info(`Database disconnected from ${this.url}`);
|
|
72
|
+
});
|
|
73
|
+
connection.on("reconnected", () => {
|
|
74
|
+
this.logger.info(`Database reconnected to ${this.url}`);
|
|
75
|
+
});
|
|
76
|
+
connection.on("reconnectFailed", () => {
|
|
77
|
+
this.logger.error(`Database reconnect failed to ${this.url}`);
|
|
78
|
+
});
|
|
79
|
+
connection.on("close", () => {
|
|
80
|
+
this.logger.info(`Database connection to ${this.url} closed`);
|
|
81
|
+
});
|
|
82
|
+
connection.on("fullsetup", () => {
|
|
83
|
+
this.logger.info(`Database connection to ${this.url} is fully setup`);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
this.tables = {
|
|
87
|
+
captcha: this.connection.model("Captcha", typesDatabase.CaptchaRecordSchema),
|
|
88
|
+
powCaptcha: this.connection.model("PowCaptcha", typesDatabase.PowCaptchaRecordSchema),
|
|
89
|
+
dataset: this.connection.model("Dataset", typesDatabase.DatasetRecordSchema),
|
|
90
|
+
solution: this.connection.model("Solution", typesDatabase.SolutionRecordSchema),
|
|
91
|
+
commitment: this.connection.model("UserCommitment", typesDatabase.UserCommitmentRecordSchema),
|
|
92
|
+
usersolution: this.connection.model("UserSolution", typesDatabase.UserSolutionRecordSchema),
|
|
93
|
+
pending: this.connection.model("Pending", typesDatabase.PendingRecordSchema),
|
|
94
|
+
scheduler: this.connection.model("Scheduler", typesDatabase.ScheduledTaskRecordSchema)
|
|
95
|
+
};
|
|
81
96
|
}
|
|
82
97
|
/** Close connection to the database */
|
|
83
98
|
async close() {
|
|
84
99
|
this.logger.debug(`Closing connection to ${this.url}`);
|
|
85
|
-
await
|
|
86
|
-
mongoose.connection.close().then(() => {
|
|
87
|
-
this.logger.debug(`Connection to ${this.url} closed`);
|
|
88
|
-
resolve();
|
|
89
|
-
}).catch(reject);
|
|
90
|
-
});
|
|
100
|
+
await this.connection?.close();
|
|
91
101
|
}
|
|
92
102
|
/**
|
|
93
103
|
* @description Load a dataset to the database
|
|
94
104
|
* @param {Dataset} dataset
|
|
95
105
|
*/
|
|
96
106
|
async storeDataset(dataset) {
|
|
97
|
-
var _a, _b, _c;
|
|
98
107
|
try {
|
|
99
108
|
this.logger.debug(`Storing dataset in database`);
|
|
100
109
|
const parsedDataset = types.DatasetWithIdsAndTreeSchema.parse(dataset);
|
|
@@ -105,21 +114,21 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
105
114
|
contentTree: parsedDataset.contentTree,
|
|
106
115
|
solutionTree: parsedDataset.solutionTree
|
|
107
116
|
};
|
|
108
|
-
await
|
|
117
|
+
await this.tables?.dataset.updateOne(
|
|
109
118
|
{ datasetId: parsedDataset.datasetId },
|
|
110
119
|
{ $set: datasetDoc },
|
|
111
120
|
{ upsert: true }
|
|
112
|
-
)
|
|
121
|
+
);
|
|
113
122
|
const captchaDocs = parsedDataset.captchas.map(({ solution, ...captcha }, index) => ({
|
|
114
123
|
...captcha,
|
|
115
124
|
datasetId: parsedDataset.datasetId,
|
|
116
125
|
datasetContentId: parsedDataset.datasetContentId,
|
|
117
126
|
index,
|
|
118
|
-
solved: !!
|
|
127
|
+
solved: !!solution?.length
|
|
119
128
|
}));
|
|
120
129
|
this.logger.debug(`Inserting captcha records`);
|
|
121
130
|
if (captchaDocs.length) {
|
|
122
|
-
await
|
|
131
|
+
await this.tables?.captcha.bulkWrite(
|
|
123
132
|
captchaDocs.map((captchaDoc) => ({
|
|
124
133
|
updateOne: {
|
|
125
134
|
filter: { captchaId: captchaDoc.captchaId },
|
|
@@ -127,9 +136,9 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
127
136
|
upsert: true
|
|
128
137
|
}
|
|
129
138
|
}))
|
|
130
|
-
)
|
|
139
|
+
);
|
|
131
140
|
}
|
|
132
|
-
const captchaSolutionDocs = parsedDataset.captchas.filter(({ solution }) => solution
|
|
141
|
+
const captchaSolutionDocs = parsedDataset.captchas.filter(({ solution }) => solution?.length).map((captcha) => ({
|
|
133
142
|
captchaId: captcha.captchaId,
|
|
134
143
|
captchaContentId: captcha.captchaContentId,
|
|
135
144
|
solution: captcha.solution,
|
|
@@ -139,7 +148,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
139
148
|
}));
|
|
140
149
|
this.logger.debug(`Inserting solution records`);
|
|
141
150
|
if (captchaSolutionDocs.length) {
|
|
142
|
-
await
|
|
151
|
+
await this.tables?.solution.bulkWrite(
|
|
143
152
|
captchaSolutionDocs.map((captchaSolutionDoc) => ({
|
|
144
153
|
updateOne: {
|
|
145
154
|
filter: { captchaId: captchaSolutionDoc.captchaId },
|
|
@@ -147,7 +156,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
147
156
|
upsert: true
|
|
148
157
|
}
|
|
149
158
|
}))
|
|
150
|
-
)
|
|
159
|
+
);
|
|
151
160
|
}
|
|
152
161
|
this.logger.debug(`Dataset stored in database`);
|
|
153
162
|
} catch (err) {
|
|
@@ -161,20 +170,18 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
161
170
|
* @param {string} datasetId
|
|
162
171
|
*/
|
|
163
172
|
async getSolutions(datasetId) {
|
|
164
|
-
|
|
165
|
-
const docs = await ((_a = this.tables) == null ? void 0 : _a.solution.find({ datasetId }).lean());
|
|
173
|
+
const docs = await this.tables?.solution.find({ datasetId }).lean();
|
|
166
174
|
return docs ? docs : [];
|
|
167
175
|
}
|
|
168
176
|
/** @description Get a dataset from the database
|
|
169
177
|
* @param {string} datasetId
|
|
170
178
|
*/
|
|
171
179
|
async getDataset(datasetId) {
|
|
172
|
-
|
|
173
|
-
const datasetDoc = await ((_a = this.tables) == null ? void 0 : _a.dataset.findOne({ datasetId }).lean());
|
|
180
|
+
const datasetDoc = await this.tables?.dataset.findOne({ datasetId }).lean();
|
|
174
181
|
if (datasetDoc) {
|
|
175
182
|
const { datasetContentId, format, contentTree, solutionTree } = datasetDoc;
|
|
176
|
-
const captchas = await
|
|
177
|
-
const solutions = await
|
|
183
|
+
const captchas = await this.tables?.captcha.find({ datasetId }).lean() || [];
|
|
184
|
+
const solutions = await this.tables?.solution.find({ datasetId }).lean() || [];
|
|
178
185
|
const solutionsKeyed = {};
|
|
179
186
|
for (const solution of solutions) {
|
|
180
187
|
solutionsKeyed[solution.captchaId] = solution;
|
|
@@ -211,14 +218,13 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
211
218
|
* @param {number} size the number of records to be returned
|
|
212
219
|
*/
|
|
213
220
|
async getRandomCaptcha(solved, datasetId, size) {
|
|
214
|
-
var _a;
|
|
215
221
|
if (!is.isHex(datasetId)) {
|
|
216
222
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
217
223
|
context: { failedFuncName: this.getRandomCaptcha.name, datasetId }
|
|
218
224
|
});
|
|
219
225
|
}
|
|
220
226
|
const sampleSize = size ? Math.abs(Math.trunc(size)) : 1;
|
|
221
|
-
const cursor =
|
|
227
|
+
const cursor = this.tables?.captcha.aggregate([
|
|
222
228
|
{ $match: { datasetId, solved } },
|
|
223
229
|
{ $sample: { size: sampleSize } },
|
|
224
230
|
{
|
|
@@ -245,8 +251,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
245
251
|
* @param {string[]} captchaId
|
|
246
252
|
*/
|
|
247
253
|
async getCaptchaById(captchaId) {
|
|
248
|
-
|
|
249
|
-
const cursor = (_a = this.tables) == null ? void 0 : _a.captcha.find({ captchaId: { $in: captchaId } }).lean();
|
|
254
|
+
const cursor = this.tables?.captcha.find({ captchaId: { $in: captchaId } }).lean();
|
|
250
255
|
const docs = await cursor;
|
|
251
256
|
if (docs && docs.length) {
|
|
252
257
|
return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
|
|
@@ -261,14 +266,13 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
261
266
|
* @param {string} datasetId the id of the data set
|
|
262
267
|
*/
|
|
263
268
|
async updateCaptcha(captcha, datasetId) {
|
|
264
|
-
var _a;
|
|
265
269
|
if (!is.isHex(datasetId)) {
|
|
266
270
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
267
271
|
context: { failedFuncName: this.updateCaptcha.name, datasetId }
|
|
268
272
|
});
|
|
269
273
|
}
|
|
270
274
|
try {
|
|
271
|
-
await
|
|
275
|
+
await this.tables?.captcha.updateOne({ datasetId }, { $set: captcha }, { upsert: false });
|
|
272
276
|
} catch (err) {
|
|
273
277
|
throw new common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
|
|
274
278
|
context: { failedFuncName: this.getDatasetDetails.name, error: err }
|
|
@@ -279,20 +283,18 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
279
283
|
* @description Remove captchas
|
|
280
284
|
*/
|
|
281
285
|
async removeCaptchas(captchaIds) {
|
|
282
|
-
|
|
283
|
-
await ((_a = this.tables) == null ? void 0 : _a.captcha.deleteMany({ captchaId: { $in: captchaIds } }));
|
|
286
|
+
await this.tables?.captcha.deleteMany({ captchaId: { $in: captchaIds } });
|
|
284
287
|
}
|
|
285
288
|
/**
|
|
286
289
|
* @description Get a dataset by Id
|
|
287
290
|
*/
|
|
288
291
|
async getDatasetDetails(datasetId) {
|
|
289
|
-
var _a;
|
|
290
292
|
if (!is.isHex(datasetId)) {
|
|
291
293
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
292
294
|
context: { failedFuncName: this.getDatasetDetails.name, datasetId }
|
|
293
295
|
});
|
|
294
296
|
}
|
|
295
|
-
const doc = await
|
|
297
|
+
const doc = await this.tables?.dataset.findOne({ datasetId }).lean();
|
|
296
298
|
if (doc) {
|
|
297
299
|
return doc;
|
|
298
300
|
}
|
|
@@ -304,16 +306,15 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
304
306
|
* @description Store a Dapp User's captcha solution commitment
|
|
305
307
|
*/
|
|
306
308
|
async storeDappUserSolution(captchas, commit) {
|
|
307
|
-
var _a, _b;
|
|
308
309
|
const commitmentRecord = typesDatabase.UserCommitmentSchema.parse(commit);
|
|
309
310
|
if (captchas.length) {
|
|
310
|
-
await
|
|
311
|
+
await this.tables?.commitment.updateOne(
|
|
311
312
|
{
|
|
312
313
|
id: commit.id
|
|
313
314
|
},
|
|
314
315
|
commitmentRecord,
|
|
315
316
|
{ upsert: true }
|
|
316
|
-
)
|
|
317
|
+
);
|
|
317
318
|
const ops = captchas.map((captcha) => ({
|
|
318
319
|
updateOne: {
|
|
319
320
|
filter: { commitmentId: commit.id, captchaId: captcha.captchaId },
|
|
@@ -330,54 +331,136 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
330
331
|
upsert: true
|
|
331
332
|
}
|
|
332
333
|
}));
|
|
333
|
-
await
|
|
334
|
+
await this.tables?.usersolution.bulkWrite(ops);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* @description Adds a new PoW Captcha record to the database.
|
|
339
|
+
* @param {string} challenge The challenge string for the captcha.
|
|
340
|
+
* @param {boolean} checked Indicates if the captcha has been checked.
|
|
341
|
+
* @returns {Promise<void>} A promise that resolves when the record is added.
|
|
342
|
+
*/
|
|
343
|
+
async storePowCaptchaRecord(challenge, checked) {
|
|
344
|
+
if (!this.tables) {
|
|
345
|
+
throw new common.ProsopoEnvError("DATABASE.DATABASE_UNDEFINED", {
|
|
346
|
+
context: { failedFuncName: this.storePowCaptchaRecord.name },
|
|
347
|
+
logger: this.logger
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
const powCaptchaRecord = {
|
|
351
|
+
challenge,
|
|
352
|
+
checked
|
|
353
|
+
};
|
|
354
|
+
try {
|
|
355
|
+
await this.tables.powCaptcha.create(powCaptchaRecord);
|
|
356
|
+
this.logger.info("PowCaptcha record added successfully", { challenge, checked });
|
|
357
|
+
} catch (error) {
|
|
358
|
+
this.logger.error("Failed to add PowCaptcha record", { error, challenge, checked });
|
|
359
|
+
throw new common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
|
|
360
|
+
context: { error, challenge, checked },
|
|
361
|
+
logger: this.logger
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* @description Retrieves a PoW Captcha record by its challenge string.
|
|
367
|
+
* @param {string} challenge The challenge string to search for.
|
|
368
|
+
* @returns {Promise<PowCaptcha | null>} A promise that resolves with the found record or null if not found.
|
|
369
|
+
*/
|
|
370
|
+
async getPowCaptchaRecordByChallenge(challenge) {
|
|
371
|
+
if (!this.tables) {
|
|
372
|
+
throw new common.ProsopoEnvError("DATABASE.DATABASE_UNDEFINED", {
|
|
373
|
+
context: { failedFuncName: this.getPowCaptchaRecordByChallenge.name },
|
|
374
|
+
logger: this.logger
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
const record = await this.tables.powCaptcha.findOne({ challenge }).lean();
|
|
379
|
+
if (record) {
|
|
380
|
+
this.logger.info("PowCaptcha record retrieved successfully", { challenge });
|
|
381
|
+
return record;
|
|
382
|
+
} else {
|
|
383
|
+
this.logger.info("No PowCaptcha record found", { challenge });
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
} catch (error) {
|
|
387
|
+
this.logger.error("Failed to retrieve PowCaptcha record", { error, challenge });
|
|
388
|
+
throw new common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
389
|
+
context: { error, challenge },
|
|
390
|
+
logger: this.logger
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* @description Updates a PoW Captcha record in the database.
|
|
396
|
+
* @param {string} challenge The challenge string of the captcha to be updated.
|
|
397
|
+
* @param {boolean} checked New value indicating whether the captcha has been checked.
|
|
398
|
+
* @returns {Promise<void>} A promise that resolves when the record is updated.
|
|
399
|
+
*/
|
|
400
|
+
async updatePowCaptchaRecord(challenge, checked) {
|
|
401
|
+
if (!this.tables) {
|
|
402
|
+
throw new common.ProsopoEnvError("DATABASE.DATABASE_UNDEFINED", {
|
|
403
|
+
context: { failedFuncName: this.updatePowCaptchaRecord.name },
|
|
404
|
+
logger: this.logger
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
const updateResult = await this.tables.powCaptcha.updateOne({ challenge }, { $set: { checked } });
|
|
409
|
+
if (updateResult.matchedCount === 0) {
|
|
410
|
+
this.logger.info("No PowCaptcha record found to update", { challenge, checked });
|
|
411
|
+
throw new common.ProsopoDBError("DATABASE.CAPTCHA_GET_FAILED", {
|
|
412
|
+
context: { challenge, checked },
|
|
413
|
+
logger: this.logger
|
|
414
|
+
});
|
|
415
|
+
} else {
|
|
416
|
+
this.logger.info("PowCaptcha record updated successfully", { challenge, checked });
|
|
417
|
+
}
|
|
418
|
+
} catch (error) {
|
|
419
|
+
this.logger.error("Failed to update PowCaptcha record", { error, challenge, checked });
|
|
420
|
+
throw new common.ProsopoDBError("DATABASE.CAPTCHA_UPDATE_FAILED", {
|
|
421
|
+
context: { error, challenge, checked },
|
|
422
|
+
logger: this.logger
|
|
423
|
+
});
|
|
334
424
|
}
|
|
335
425
|
}
|
|
336
426
|
/** @description Get processed Dapp User captcha solutions from the user solution table
|
|
337
427
|
*/
|
|
338
428
|
async getProcessedDappUserSolutions() {
|
|
339
|
-
|
|
340
|
-
const docs = await ((_a = this.tables) == null ? void 0 : _a.usersolution.find({ processed: true }).lean());
|
|
429
|
+
const docs = await this.tables?.usersolution.find({ processed: true }).lean();
|
|
341
430
|
return docs ? docs.map((doc) => typesDatabase.UserSolutionSchema.parse(doc)) : [];
|
|
342
431
|
}
|
|
343
432
|
/** @description Get processed Dapp User captcha commitments from the commitments table
|
|
344
433
|
*/
|
|
345
434
|
async getProcessedDappUserCommitments() {
|
|
346
|
-
|
|
347
|
-
const docs = await ((_a = this.tables) == null ? void 0 : _a.commitment.find({ processed: true }).lean());
|
|
435
|
+
const docs = await this.tables?.commitment.find({ processed: true }).lean();
|
|
348
436
|
return docs ? docs.map((doc) => typesDatabase.UserCommitmentSchema.parse(doc)) : [];
|
|
349
437
|
}
|
|
350
438
|
/** @description Get Dapp User captcha commitments from the commitments table that have not been batched on-chain
|
|
351
439
|
*/
|
|
352
440
|
async getUnbatchedDappUserCommitments() {
|
|
353
|
-
|
|
354
|
-
const docs = await ((_a = this.tables) == null ? void 0 : _a.commitment.find({ batched: false }).lean());
|
|
441
|
+
const docs = await this.tables?.commitment.find({ batched: false }).lean();
|
|
355
442
|
return docs ? docs.map((doc) => typesDatabase.UserCommitmentSchema.parse(doc)) : [];
|
|
356
443
|
}
|
|
357
444
|
/** @description Get Dapp User captcha commitments from the commitments table that have been batched on-chain
|
|
358
445
|
*/
|
|
359
446
|
async getBatchedDappUserCommitments() {
|
|
360
|
-
|
|
361
|
-
const docs = await ((_a = this.tables) == null ? void 0 : _a.commitment.find({ batched: true }).lean());
|
|
447
|
+
const docs = await this.tables?.commitment.find({ batched: true }).lean();
|
|
362
448
|
return docs ? docs.map((doc) => typesDatabase.UserCommitmentSchema.parse(doc)) : [];
|
|
363
449
|
}
|
|
364
450
|
/** @description Remove processed Dapp User captcha solutions from the user solution table
|
|
365
451
|
*/
|
|
366
452
|
async removeProcessedDappUserSolutions(commitmentIds) {
|
|
367
|
-
|
|
368
|
-
return await ((_a = this.tables) == null ? void 0 : _a.usersolution.deleteMany({ processed: true, commitmentId: { $in: commitmentIds } }));
|
|
453
|
+
return await this.tables?.usersolution.deleteMany({ processed: true, commitmentId: { $in: commitmentIds } });
|
|
369
454
|
}
|
|
370
455
|
/** @description Remove processed Dapp User captcha commitments from the user commitments table
|
|
371
456
|
*/
|
|
372
457
|
async removeProcessedDappUserCommitments(commitmentIds) {
|
|
373
|
-
|
|
374
|
-
return await ((_a = this.tables) == null ? void 0 : _a.commitment.deleteMany({ processed: true, id: { $in: commitmentIds } }));
|
|
458
|
+
return await this.tables?.commitment.deleteMany({ processed: true, id: { $in: commitmentIds } });
|
|
375
459
|
}
|
|
376
460
|
/**
|
|
377
461
|
* @description Store a Dapp User's pending record
|
|
378
462
|
*/
|
|
379
463
|
async storeDappUserPending(userAccount, requestHash, salt, deadlineTimestamp, requestedAtBlock) {
|
|
380
|
-
var _a;
|
|
381
464
|
if (!is.isHex(requestHash)) {
|
|
382
465
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
383
466
|
context: { failedFuncName: this.storeDappUserPending.name, requestHash }
|
|
@@ -391,19 +474,18 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
391
474
|
deadlineTimestamp,
|
|
392
475
|
requestedAtBlock
|
|
393
476
|
};
|
|
394
|
-
await
|
|
477
|
+
await this.tables?.pending.updateOne({ requestHash }, { $set: pendingRecord }, { upsert: true });
|
|
395
478
|
}
|
|
396
479
|
/**
|
|
397
480
|
* @description Get a Dapp user's pending record
|
|
398
481
|
*/
|
|
399
482
|
async getDappUserPending(requestHash) {
|
|
400
|
-
var _a;
|
|
401
483
|
if (!is.isHex(requestHash)) {
|
|
402
484
|
throw new common.ProsopoEnvError("DATABASE.INVALID_HASH", {
|
|
403
485
|
context: { failedFuncName: this.getDappUserPending.name, requestHash }
|
|
404
486
|
});
|
|
405
487
|
}
|
|
406
|
-
const doc = await
|
|
488
|
+
const doc = await this.tables?.pending.findOne({ requestHash }).lean();
|
|
407
489
|
if (doc) {
|
|
408
490
|
return doc;
|
|
409
491
|
}
|
|
@@ -415,13 +497,12 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
415
497
|
* @description Update a Dapp User's pending record
|
|
416
498
|
*/
|
|
417
499
|
async updateDappUserPendingStatus(userAccount, requestHash, approve) {
|
|
418
|
-
var _a;
|
|
419
500
|
if (!is.isHex(requestHash)) {
|
|
420
501
|
throw new common.ProsopoEnvError("DATABASE.INVALID_HASH", {
|
|
421
502
|
context: { failedFuncName: this.updateDappUserPendingStatus.name, requestHash }
|
|
422
503
|
});
|
|
423
504
|
}
|
|
424
|
-
await
|
|
505
|
+
await this.tables?.pending.updateOne(
|
|
425
506
|
{ requestHash },
|
|
426
507
|
{
|
|
427
508
|
$set: {
|
|
@@ -432,14 +513,13 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
432
513
|
}
|
|
433
514
|
},
|
|
434
515
|
{ upsert: true }
|
|
435
|
-
)
|
|
516
|
+
);
|
|
436
517
|
}
|
|
437
518
|
/**
|
|
438
519
|
* @description Get all unsolved captchas
|
|
439
520
|
*/
|
|
440
521
|
async getAllCaptchasByDatasetId(datasetId, state) {
|
|
441
|
-
|
|
442
|
-
const cursor = (_a = this.tables) == null ? void 0 : _a.captcha.find({
|
|
522
|
+
const cursor = this.tables?.captcha.find({
|
|
443
523
|
datasetId,
|
|
444
524
|
solved: state === types.CaptchaStates.Solved
|
|
445
525
|
}).lean();
|
|
@@ -453,8 +533,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
453
533
|
* @description Get all dapp user solutions by captchaIds
|
|
454
534
|
*/
|
|
455
535
|
async getAllDappUserSolutions(captchaId) {
|
|
456
|
-
|
|
457
|
-
const cursor = (_b = (_a = this.tables) == null ? void 0 : _a.usersolution) == null ? void 0 : _b.find({ captchaId: { $in: captchaId } }).lean();
|
|
536
|
+
const cursor = this.tables?.usersolution?.find({ captchaId: { $in: captchaId } }).lean();
|
|
458
537
|
const docs = await cursor;
|
|
459
538
|
if (docs) {
|
|
460
539
|
return docs.map(({ _id, ...keepAttrs }) => keepAttrs);
|
|
@@ -462,8 +541,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
462
541
|
throw new common.ProsopoEnvError("DATABASE.SOLUTION_GET_FAILED");
|
|
463
542
|
}
|
|
464
543
|
async getDatasetIdWithSolvedCaptchasOfSizeN(solvedCaptchaCount) {
|
|
465
|
-
|
|
466
|
-
const cursor = (_a = this.tables) == null ? void 0 : _a.solution.aggregate([
|
|
544
|
+
const cursor = this.tables?.solution.aggregate([
|
|
467
545
|
{
|
|
468
546
|
$match: {}
|
|
469
547
|
},
|
|
@@ -489,14 +567,13 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
489
567
|
throw new common.ProsopoDBError("DATABASE.DATASET_WITH_SOLUTIONS_GET_FAILED");
|
|
490
568
|
}
|
|
491
569
|
async getRandomSolvedCaptchasFromSingleDataset(datasetId, size) {
|
|
492
|
-
var _a;
|
|
493
570
|
if (!is.isHex(datasetId)) {
|
|
494
571
|
throw new common.ProsopoDBError("DATABASE.INVALID_HASH", {
|
|
495
572
|
context: { failedFuncName: this.getRandomSolvedCaptchasFromSingleDataset.name, datasetId }
|
|
496
573
|
});
|
|
497
574
|
}
|
|
498
575
|
const sampleSize = size ? Math.abs(Math.trunc(size)) : 1;
|
|
499
|
-
const cursor =
|
|
576
|
+
const cursor = this.tables?.solution.aggregate([
|
|
500
577
|
{ $match: { datasetId } },
|
|
501
578
|
{ $sample: { size: sampleSize } },
|
|
502
579
|
{
|
|
@@ -520,8 +597,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
520
597
|
* @param {string[]} commitmentId
|
|
521
598
|
*/
|
|
522
599
|
async getDappUserSolutionById(commitmentId) {
|
|
523
|
-
|
|
524
|
-
const cursor = (_b = (_a = this.tables) == null ? void 0 : _a.usersolution) == null ? void 0 : _b.findOne(
|
|
600
|
+
const cursor = this.tables?.usersolution?.findOne(
|
|
525
601
|
{
|
|
526
602
|
commitmentId
|
|
527
603
|
},
|
|
@@ -540,8 +616,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
540
616
|
* @param commitmentId
|
|
541
617
|
*/
|
|
542
618
|
async getDappUserCommitmentById(commitmentId) {
|
|
543
|
-
|
|
544
|
-
const commitmentCursor = (_b = (_a = this.tables) == null ? void 0 : _a.commitment) == null ? void 0 : _b.findOne({ id: commitmentId }).lean();
|
|
619
|
+
const commitmentCursor = this.tables?.commitment?.findOne({ id: commitmentId }).lean();
|
|
545
620
|
const doc = await commitmentCursor;
|
|
546
621
|
return doc ? typesDatabase.UserCommitmentSchema.parse(doc) : void 0;
|
|
547
622
|
}
|
|
@@ -550,8 +625,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
550
625
|
* @param {string[]} userAccount
|
|
551
626
|
*/
|
|
552
627
|
async getDappUserCommitmentByAccount(userAccount) {
|
|
553
|
-
|
|
554
|
-
const docs = await ((_b = (_a = this.tables) == null ? void 0 : _a.commitment) == null ? void 0 : _b.find({ userAccount }).lean());
|
|
628
|
+
const docs = await this.tables?.commitment?.find({ userAccount }).lean();
|
|
555
629
|
return docs ? docs : [];
|
|
556
630
|
}
|
|
557
631
|
/**
|
|
@@ -559,13 +633,12 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
559
633
|
* @param {string[]} commitmentId
|
|
560
634
|
*/
|
|
561
635
|
async approveDappUserCommitment(commitmentId) {
|
|
562
|
-
var _a, _b;
|
|
563
636
|
try {
|
|
564
|
-
await
|
|
637
|
+
await this.tables?.commitment?.findOneAndUpdate(
|
|
565
638
|
{ id: commitmentId },
|
|
566
639
|
{ $set: { status: typesReturns.CaptchaStatus.approved } },
|
|
567
640
|
{ upsert: false }
|
|
568
|
-
).lean()
|
|
641
|
+
).lean();
|
|
569
642
|
} catch (err) {
|
|
570
643
|
throw new common.ProsopoDBError("DATABASE.SOLUTION_APPROVE_FAILED", { context: { error: err, commitmentId } });
|
|
571
644
|
}
|
|
@@ -575,9 +648,8 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
575
648
|
* @param {string[]} captchaIds
|
|
576
649
|
*/
|
|
577
650
|
async flagProcessedDappUserSolutions(captchaIds) {
|
|
578
|
-
var _a, _b;
|
|
579
651
|
try {
|
|
580
|
-
await
|
|
652
|
+
await this.tables?.usersolution?.updateMany({ captchaId: { $in: captchaIds } }, { $set: { processed: true } }, { upsert: false }).lean();
|
|
581
653
|
} catch (err) {
|
|
582
654
|
throw new common.ProsopoDBError("DATABASE.SOLUTION_FLAG_FAILED", { context: { error: err, captchaIds } });
|
|
583
655
|
}
|
|
@@ -587,10 +659,9 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
587
659
|
* @param {string[]} commitmentIds
|
|
588
660
|
*/
|
|
589
661
|
async flagProcessedDappUserCommitments(commitmentIds) {
|
|
590
|
-
var _a, _b;
|
|
591
662
|
try {
|
|
592
663
|
const distinctCommitmentIds = [...new Set(commitmentIds)];
|
|
593
|
-
await
|
|
664
|
+
await this.tables?.commitment?.updateMany({ id: { $in: distinctCommitmentIds } }, { $set: { processed: true } }, { upsert: false }).lean();
|
|
594
665
|
} catch (err) {
|
|
595
666
|
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", { context: { error: err, commitmentIds } });
|
|
596
667
|
}
|
|
@@ -600,10 +671,9 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
600
671
|
* @param {string[]} commitmentIds
|
|
601
672
|
*/
|
|
602
673
|
async flagBatchedDappUserCommitments(commitmentIds) {
|
|
603
|
-
var _a, _b;
|
|
604
674
|
try {
|
|
605
675
|
const distinctCommitmentIds = [...new Set(commitmentIds)];
|
|
606
|
-
await
|
|
676
|
+
await this.tables?.commitment?.updateMany({ id: { $in: distinctCommitmentIds } }, { $set: { batched: true } }, { upsert: false }).lean();
|
|
607
677
|
} catch (err) {
|
|
608
678
|
throw new common.ProsopoDBError("DATABASE.COMMITMENT_FLAG_FAILED", { context: { error: err, commitmentIds } });
|
|
609
679
|
}
|
|
@@ -612,9 +682,8 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
612
682
|
* @description Get the last batch commit time or return 0 if none
|
|
613
683
|
*/
|
|
614
684
|
async getLastBatchCommitTime() {
|
|
615
|
-
|
|
616
|
-
const
|
|
617
|
-
const doc = await (cursor == null ? void 0 : cursor.lean());
|
|
685
|
+
const cursor = this.tables?.scheduler?.findOne({ processName: types.ScheduledTaskNames.BatchCommitment, status: types.ScheduledTaskStatus.Completed }).sort({ timestamp: -1 });
|
|
686
|
+
const doc = await cursor?.lean();
|
|
618
687
|
if (doc) {
|
|
619
688
|
return doc.datetime;
|
|
620
689
|
}
|
|
@@ -624,27 +693,24 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
624
693
|
* @description Get a scheduled task status record by task ID and status
|
|
625
694
|
*/
|
|
626
695
|
async getScheduledTaskStatus(taskId, status) {
|
|
627
|
-
|
|
628
|
-
const cursor = await ((_b = (_a = this.tables) == null ? void 0 : _a.scheduler) == null ? void 0 : _b.findOne({ taskId, status }).lean());
|
|
696
|
+
const cursor = await this.tables?.scheduler?.findOne({ taskId, status }).lean();
|
|
629
697
|
return cursor ? cursor : void 0;
|
|
630
698
|
}
|
|
631
699
|
/**
|
|
632
700
|
* @description Get the most recent scheduled task status record for a given task
|
|
633
701
|
*/
|
|
634
702
|
async getLastScheduledTaskStatus(task, status) {
|
|
635
|
-
var _a, _b;
|
|
636
703
|
const lookup = { processName: task };
|
|
637
704
|
if (status) {
|
|
638
705
|
lookup["status"] = status;
|
|
639
706
|
}
|
|
640
|
-
const cursor = await
|
|
707
|
+
const cursor = await this.tables?.scheduler?.findOne(lookup).sort({ datetime: -1 }).lean();
|
|
641
708
|
return cursor ? cursor : void 0;
|
|
642
709
|
}
|
|
643
710
|
/**
|
|
644
711
|
* @description Store the status of a scheduled task and an optional result
|
|
645
712
|
*/
|
|
646
713
|
async storeScheduledTaskStatus(taskId, task, status, result) {
|
|
647
|
-
var _a;
|
|
648
714
|
const now = /* @__PURE__ */ new Date();
|
|
649
715
|
const doc = typesDatabase.ScheduledTaskSchema.parse({
|
|
650
716
|
taskId,
|
|
@@ -653,7 +719,7 @@ class ProsopoDatabase extends common.AsyncFactory {
|
|
|
653
719
|
status,
|
|
654
720
|
...result && { result }
|
|
655
721
|
});
|
|
656
|
-
await
|
|
722
|
+
await this.tables?.scheduler.create(doc);
|
|
657
723
|
}
|
|
658
724
|
}
|
|
659
725
|
exports.ProsopoDatabase = ProsopoDatabase;
|