@xtr-dev/rondevu-server 0.5.22 → 0.5.25
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/.github/workflows/docker-publish.yml +1 -0
- package/dist/index.js +106 -4
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/src/config.ts +1 -1
- package/src/rpc.ts +5 -2
- package/src/storage/d1.ts +49 -42
- package/src/storage/memory.ts +20 -7
- package/src/storage/mysql.ts +3 -2
- package/src/storage/postgres.ts +3 -2
- package/src/storage/sqlite.ts +3 -2
- package/src/storage/types.ts +3 -2
package/dist/index.js
CHANGED
|
@@ -354,6 +354,38 @@ var init_memory = __esm({
|
|
|
354
354
|
const candidates = this.iceCandidates.get(offerId);
|
|
355
355
|
return candidates ? candidates.length : 0;
|
|
356
356
|
}
|
|
357
|
+
async countOffersByTags(tags, unique = false) {
|
|
358
|
+
const result = /* @__PURE__ */ new Map();
|
|
359
|
+
if (tags.length === 0) return result;
|
|
360
|
+
const now = Date.now();
|
|
361
|
+
for (const tag of tags) {
|
|
362
|
+
const offerIds = this.offersByTag.get(tag);
|
|
363
|
+
if (!offerIds) {
|
|
364
|
+
result.set(tag, 0);
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
if (unique) {
|
|
368
|
+
const uniquePublicKeys = /* @__PURE__ */ new Set();
|
|
369
|
+
for (const offerId of offerIds) {
|
|
370
|
+
const offer = this.offers.get(offerId);
|
|
371
|
+
if (offer && offer.expiresAt > now && !offer.answererPublicKey) {
|
|
372
|
+
uniquePublicKeys.add(offer.publicKey);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
result.set(tag, uniquePublicKeys.size);
|
|
376
|
+
} else {
|
|
377
|
+
let count = 0;
|
|
378
|
+
for (const offerId of offerIds) {
|
|
379
|
+
const offer = this.offers.get(offerId);
|
|
380
|
+
if (offer && offer.expiresAt > now && !offer.answererPublicKey) {
|
|
381
|
+
count++;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
result.set(tag, count);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return result;
|
|
388
|
+
}
|
|
357
389
|
// ===== Helper Methods =====
|
|
358
390
|
removeOfferFromIndexes(offer) {
|
|
359
391
|
const publicKeyOffers = this.offersByPublicKey.get(offer.publicKey);
|
|
@@ -793,6 +825,24 @@ var init_sqlite = __esm({
|
|
|
793
825
|
const result = this.db.prepare("SELECT COUNT(*) as count FROM ice_candidates WHERE offer_id = ?").get(offerId);
|
|
794
826
|
return result.count;
|
|
795
827
|
}
|
|
828
|
+
async countOffersByTags(tags, unique = false) {
|
|
829
|
+
const result = /* @__PURE__ */ new Map();
|
|
830
|
+
if (tags.length === 0) return result;
|
|
831
|
+
const now = Date.now();
|
|
832
|
+
const countColumn = unique ? "COUNT(DISTINCT o.public_key)" : "COUNT(DISTINCT o.id)";
|
|
833
|
+
const stmt = this.db.prepare(`
|
|
834
|
+
SELECT ${countColumn} as count
|
|
835
|
+
FROM offers o, json_each(o.tags) as t
|
|
836
|
+
WHERE t.value = ?
|
|
837
|
+
AND o.expires_at > ?
|
|
838
|
+
AND o.answerer_public_key IS NULL
|
|
839
|
+
`);
|
|
840
|
+
for (const tag of tags) {
|
|
841
|
+
const row = stmt.get(tag, now);
|
|
842
|
+
result.set(tag, row.count);
|
|
843
|
+
}
|
|
844
|
+
return result;
|
|
845
|
+
}
|
|
796
846
|
// ===== Helper Methods =====
|
|
797
847
|
/**
|
|
798
848
|
* Helper method to convert database row to Offer object
|
|
@@ -1181,6 +1231,24 @@ var init_mysql = __esm({
|
|
|
1181
1231
|
);
|
|
1182
1232
|
return Number(rows[0].count);
|
|
1183
1233
|
}
|
|
1234
|
+
async countOffersByTags(tags, unique = false) {
|
|
1235
|
+
const result = /* @__PURE__ */ new Map();
|
|
1236
|
+
if (tags.length === 0) return result;
|
|
1237
|
+
const now = Date.now();
|
|
1238
|
+
for (const tag of tags) {
|
|
1239
|
+
const countColumn = unique ? "COUNT(DISTINCT public_key)" : "COUNT(DISTINCT id)";
|
|
1240
|
+
const [rows] = await this.pool.query(
|
|
1241
|
+
`SELECT ${countColumn} as count
|
|
1242
|
+
FROM offers
|
|
1243
|
+
WHERE JSON_CONTAINS(tags, ?)
|
|
1244
|
+
AND expires_at > ?
|
|
1245
|
+
AND answerer_public_key IS NULL`,
|
|
1246
|
+
[JSON.stringify(tag), now]
|
|
1247
|
+
);
|
|
1248
|
+
result.set(tag, Number(rows[0].count));
|
|
1249
|
+
}
|
|
1250
|
+
return result;
|
|
1251
|
+
}
|
|
1184
1252
|
// ===== Helper Methods =====
|
|
1185
1253
|
rowToOffer(row) {
|
|
1186
1254
|
return {
|
|
@@ -1581,6 +1649,24 @@ var init_postgres = __esm({
|
|
|
1581
1649
|
);
|
|
1582
1650
|
return Number(result.rows[0].count);
|
|
1583
1651
|
}
|
|
1652
|
+
async countOffersByTags(tags, unique = false) {
|
|
1653
|
+
const result = /* @__PURE__ */ new Map();
|
|
1654
|
+
if (tags.length === 0) return result;
|
|
1655
|
+
const now = Date.now();
|
|
1656
|
+
for (const tag of tags) {
|
|
1657
|
+
const countColumn = unique ? "COUNT(DISTINCT public_key)" : "COUNT(DISTINCT id)";
|
|
1658
|
+
const queryResult = await this.pool.query(
|
|
1659
|
+
`SELECT ${countColumn} as count
|
|
1660
|
+
FROM offers
|
|
1661
|
+
WHERE tags ? $1
|
|
1662
|
+
AND expires_at > $2
|
|
1663
|
+
AND answerer_public_key IS NULL`,
|
|
1664
|
+
[tag, now]
|
|
1665
|
+
);
|
|
1666
|
+
result.set(tag, Number(queryResult.rows[0].count));
|
|
1667
|
+
}
|
|
1668
|
+
return result;
|
|
1669
|
+
}
|
|
1584
1670
|
// ===== Helper Methods =====
|
|
1585
1671
|
rowToOffer(row) {
|
|
1586
1672
|
return {
|
|
@@ -2365,6 +2451,22 @@ var handlers = {
|
|
|
2365
2451
|
expiresAt: offer.expiresAt
|
|
2366
2452
|
};
|
|
2367
2453
|
},
|
|
2454
|
+
/**
|
|
2455
|
+
* Count available offers by tags
|
|
2456
|
+
*/
|
|
2457
|
+
async countOffersByTags(params, publicKey, timestamp, signature, storage, config, request) {
|
|
2458
|
+
const { tags, unique } = params;
|
|
2459
|
+
const tagsValidation = validateTags(tags);
|
|
2460
|
+
if (!tagsValidation.valid) {
|
|
2461
|
+
throw new RpcError(ErrorCodes.INVALID_TAG, tagsValidation.error || "Invalid tags");
|
|
2462
|
+
}
|
|
2463
|
+
const counts = await storage.countOffersByTags(tags, unique === true);
|
|
2464
|
+
const result = {};
|
|
2465
|
+
for (const [tag, count] of counts) {
|
|
2466
|
+
result[tag] = count;
|
|
2467
|
+
}
|
|
2468
|
+
return { counts: result };
|
|
2469
|
+
},
|
|
2368
2470
|
/**
|
|
2369
2471
|
* Publish offers with tags
|
|
2370
2472
|
*/
|
|
@@ -2661,7 +2763,7 @@ var handlers = {
|
|
|
2661
2763
|
};
|
|
2662
2764
|
}
|
|
2663
2765
|
};
|
|
2664
|
-
var UNAUTHENTICATED_METHODS = /* @__PURE__ */ new Set(["discover"]);
|
|
2766
|
+
var UNAUTHENTICATED_METHODS = /* @__PURE__ */ new Set(["discover", "countOffersByTags"]);
|
|
2665
2767
|
async function handleRpc(requests, ctx, storage, config) {
|
|
2666
2768
|
const responses = [];
|
|
2667
2769
|
const clientIp = ctx.req.header("cf-connecting-ip") || ctx.req.header("x-real-ip") || ctx.req.header("x-forwarded-for")?.split(",")[0].trim() || void 0;
|
|
@@ -2898,7 +3000,7 @@ function createApp(storage, config) {
|
|
|
2898
3000
|
}
|
|
2899
3001
|
|
|
2900
3002
|
// src/config.ts
|
|
2901
|
-
var BUILD_VERSION = true ? "
|
|
3003
|
+
var BUILD_VERSION = true ? "33a7f9c" : "unknown";
|
|
2902
3004
|
function loadConfig() {
|
|
2903
3005
|
function parsePositiveInt(value, defaultValue, name, min = 1) {
|
|
2904
3006
|
const parsed = parseInt(value || defaultValue, 10);
|
|
@@ -2948,8 +3050,8 @@ var CONFIG_DEFAULTS = {
|
|
|
2948
3050
|
offerDefaultTtl: 6e4,
|
|
2949
3051
|
offerMaxTtl: 864e5,
|
|
2950
3052
|
offerMinTtl: 6e4,
|
|
2951
|
-
answeredOfferTtl:
|
|
2952
|
-
//
|
|
3053
|
+
answeredOfferTtl: 6e4,
|
|
3054
|
+
// 60 seconds TTL after offer is answered
|
|
2953
3055
|
cleanupInterval: 6e4,
|
|
2954
3056
|
maxOffersPerRequest: 100,
|
|
2955
3057
|
maxBatchSize: 100,
|