@abtnode/db-cache 1.17.3 → 1.17.4-beta-20251201-095907-eebbbbce
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/index.cjs +34 -124
- package/dist/index.mjs +34 -121
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3,12 +3,9 @@
|
|
|
3
3
|
const path$1 = require('path');
|
|
4
4
|
const redis = require('redis');
|
|
5
5
|
const fs = require('node:fs');
|
|
6
|
-
const os = require('node:os');
|
|
7
6
|
const path = require('node:path');
|
|
8
7
|
const node_util = require('node:util');
|
|
9
8
|
const sqlite3 = require('sqlite3');
|
|
10
|
-
const crypto = require('node:crypto');
|
|
11
|
-
const lockfile = require('proper-lockfile');
|
|
12
9
|
|
|
13
10
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
14
11
|
|
|
@@ -26,11 +23,8 @@ function _interopNamespaceCompat(e) {
|
|
|
26
23
|
|
|
27
24
|
const path__default = /*#__PURE__*/_interopDefaultCompat(path$1);
|
|
28
25
|
const fs__namespace = /*#__PURE__*/_interopNamespaceCompat(fs);
|
|
29
|
-
const os__namespace = /*#__PURE__*/_interopNamespaceCompat(os);
|
|
30
26
|
const path__namespace = /*#__PURE__*/_interopNamespaceCompat(path);
|
|
31
27
|
const sqlite3__default = /*#__PURE__*/_interopDefaultCompat(sqlite3);
|
|
32
|
-
const crypto__namespace = /*#__PURE__*/_interopNamespaceCompat(crypto);
|
|
33
|
-
const lockfile__default = /*#__PURE__*/_interopDefaultCompat(lockfile);
|
|
34
28
|
|
|
35
29
|
function ulid() {
|
|
36
30
|
const alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
@@ -48,20 +42,20 @@ function ulid() {
|
|
|
48
42
|
return timeStr + rand;
|
|
49
43
|
}
|
|
50
44
|
|
|
51
|
-
var __defProp$
|
|
52
|
-
var __defNormalProp$
|
|
53
|
-
var __publicField$
|
|
54
|
-
__defNormalProp$
|
|
45
|
+
var __defProp$4 = Object.defineProperty;
|
|
46
|
+
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
47
|
+
var __publicField$4 = (obj, key, value) => {
|
|
48
|
+
__defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
55
49
|
return value;
|
|
56
50
|
};
|
|
57
51
|
const _RedisAdapter = class _RedisAdapter {
|
|
58
52
|
constructor() {
|
|
59
|
-
__publicField$
|
|
60
|
-
__publicField$
|
|
61
|
-
__publicField$
|
|
62
|
-
__publicField$
|
|
63
|
-
__publicField$
|
|
64
|
-
__publicField$
|
|
53
|
+
__publicField$4(this, "opts", null);
|
|
54
|
+
__publicField$4(this, "defaultTtl", 1e3 * 60 * 60);
|
|
55
|
+
__publicField$4(this, "url", "");
|
|
56
|
+
__publicField$4(this, "prefix", "");
|
|
57
|
+
__publicField$4(this, "prefixKey", (key) => `${this.prefix}:${key}`);
|
|
58
|
+
__publicField$4(this, "prefixKeyGroup", (key) => `${this.prefix}:group:${key}`);
|
|
65
59
|
}
|
|
66
60
|
clearAll() {
|
|
67
61
|
throw new Error("Method not implemented.");
|
|
@@ -206,8 +200,8 @@ const _RedisAdapter = class _RedisAdapter {
|
|
|
206
200
|
}
|
|
207
201
|
};
|
|
208
202
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
209
|
-
__publicField$
|
|
210
|
-
__publicField$
|
|
203
|
+
__publicField$4(_RedisAdapter, "clients", /* @__PURE__ */ new Map());
|
|
204
|
+
__publicField$4(_RedisAdapter, "initPromises", /* @__PURE__ */ new Map());
|
|
211
205
|
let RedisAdapter = _RedisAdapter;
|
|
212
206
|
|
|
213
207
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -236,67 +230,6 @@ async function withRetry(fn, {
|
|
|
236
230
|
}
|
|
237
231
|
}
|
|
238
232
|
|
|
239
|
-
var __defProp$4 = Object.defineProperty;
|
|
240
|
-
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
241
|
-
var __publicField$4 = (obj, key, value) => {
|
|
242
|
-
__defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
243
|
-
return value;
|
|
244
|
-
};
|
|
245
|
-
class FileLock {
|
|
246
|
-
// 默认 10 分钟
|
|
247
|
-
constructor(baseDir, defaultTtl) {
|
|
248
|
-
__publicField$4(this, "baseDir");
|
|
249
|
-
__publicField$4(this, "defaultTtl", 10 * 60 * 1e3);
|
|
250
|
-
this.baseDir = baseDir;
|
|
251
|
-
if (defaultTtl !== void 0) {
|
|
252
|
-
this.defaultTtl = defaultTtl;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
getLockFilePath(storageKey) {
|
|
256
|
-
const lockDir = path__namespace.join(this.baseDir, "locks");
|
|
257
|
-
if (!fs__namespace.existsSync(lockDir)) {
|
|
258
|
-
fs__namespace.mkdirSync(lockDir, { recursive: true });
|
|
259
|
-
}
|
|
260
|
-
const safeName = crypto__namespace.createHash("sha256").update(storageKey).digest("hex");
|
|
261
|
-
return path__namespace.join(lockDir, `${safeName}.lock`);
|
|
262
|
-
}
|
|
263
|
-
/**
|
|
264
|
-
* acquire 返回 true 代表成功加锁
|
|
265
|
-
* 返回 false 代表有其他进程/线程持有锁
|
|
266
|
-
*/
|
|
267
|
-
async acquire(storageKey, ttl) {
|
|
268
|
-
const lockPath = this.getLockFilePath(storageKey);
|
|
269
|
-
const effectiveTtl = ttl !== void 0 ? ttl : this.defaultTtl;
|
|
270
|
-
try {
|
|
271
|
-
try {
|
|
272
|
-
fs__namespace.writeFileSync(lockPath, "", { flag: "wx" });
|
|
273
|
-
} catch (_createErr) {
|
|
274
|
-
}
|
|
275
|
-
await lockfile__default.lock(lockPath, {
|
|
276
|
-
realpath: true,
|
|
277
|
-
stale: effectiveTtl,
|
|
278
|
-
// 超时自动释放
|
|
279
|
-
update: Math.floor(effectiveTtl / 3),
|
|
280
|
-
// 定期续租,避免长任务过期
|
|
281
|
-
retries: 0
|
|
282
|
-
});
|
|
283
|
-
return true;
|
|
284
|
-
} catch (_err) {
|
|
285
|
-
return false;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* 释放锁
|
|
290
|
-
*/
|
|
291
|
-
async release(storageKey) {
|
|
292
|
-
const lockPath = this.getLockFilePath(storageKey);
|
|
293
|
-
try {
|
|
294
|
-
await lockfile__default.unlock(lockPath);
|
|
295
|
-
} catch (_err) {
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
233
|
var __defProp$3 = Object.defineProperty;
|
|
301
234
|
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
302
235
|
var __publicField$3 = (obj, key, value) => {
|
|
@@ -362,21 +295,20 @@ const _SqliteAdapter = class _SqliteAdapter {
|
|
|
362
295
|
__publicField$3(this, "defaultTtl", 1e3 * 60 * 60);
|
|
363
296
|
__publicField$3(this, "cleanupInterval", 5 * 60 * 1e3);
|
|
364
297
|
__publicField$3(this, "dbPath", "");
|
|
365
|
-
__publicField$3(this, "fileLock", null);
|
|
366
298
|
}
|
|
367
299
|
/* ------------------------------- init ------------------------------- */
|
|
368
300
|
async ensure() {
|
|
301
|
+
const isMemory = this.opts.sqlitePath === ":memory:";
|
|
369
302
|
if (!this.dbPath) {
|
|
370
|
-
this.dbPath =
|
|
303
|
+
this.dbPath = isMemory ? ":memory:" : path__namespace.resolve(this.opts.sqlitePath);
|
|
371
304
|
this.prefix = this.opts.prefix;
|
|
372
305
|
this.defaultTtl = this.opts.ttl;
|
|
373
|
-
this.cleanupInterval = this.opts.cleanupInterval ??
|
|
374
|
-
this.fileLock = new FileLock(os__namespace.tmpdir());
|
|
306
|
+
this.cleanupInterval = this.opts.cleanupInterval ?? 5 * 60 * 1e3;
|
|
375
307
|
}
|
|
376
308
|
if (_SqliteAdapter.clients.has(this.dbPath))
|
|
377
309
|
return;
|
|
378
310
|
if (!_SqliteAdapter.initPromises.has(this.dbPath)) {
|
|
379
|
-
if (
|
|
311
|
+
if (!isMemory) {
|
|
380
312
|
const dir = path__namespace.dirname(this.dbPath);
|
|
381
313
|
if (!fs__namespace.existsSync(dir)) {
|
|
382
314
|
fs__namespace.mkdirSync(dir, { recursive: true });
|
|
@@ -434,44 +366,28 @@ const _SqliteAdapter = class _SqliteAdapter {
|
|
|
434
366
|
const storageKey = this.prefixKey(key);
|
|
435
367
|
const effectiveTtl = opts.ttl !== void 0 ? opts.ttl : this.defaultTtl;
|
|
436
368
|
const expiresAt = effectiveTtl > 0 ? Date.now() + effectiveTtl : null;
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
fileLocked = await this.fileLock.acquire(storageKey, effectiveTtl);
|
|
440
|
-
if (!fileLocked)
|
|
441
|
-
return false;
|
|
442
|
-
}
|
|
443
|
-
try {
|
|
444
|
-
if (opts.nx) {
|
|
445
|
-
const existing = await dbGet(
|
|
446
|
-
client,
|
|
447
|
-
"SELECT value FROM kvcache WHERE key = ? AND subKey = ?",
|
|
448
|
-
[storageKey, ""]
|
|
449
|
-
);
|
|
450
|
-
if (existing) {
|
|
451
|
-
return false;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
await dbRun(
|
|
369
|
+
if (opts.nx) {
|
|
370
|
+
const existing = await dbGet(
|
|
455
371
|
client,
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
VALUES (?, ?, ?, ?)
|
|
459
|
-
ON CONFLICT(key, subKey) DO UPDATE SET
|
|
460
|
-
value = excluded.value,
|
|
461
|
-
expiresAt = excluded.expiresAt
|
|
462
|
-
`,
|
|
463
|
-
[storageKey, "", this.serialize(value), expiresAt]
|
|
372
|
+
"SELECT value FROM kvcache WHERE key = ? AND subKey = ?",
|
|
373
|
+
[storageKey, ""]
|
|
464
374
|
);
|
|
465
|
-
if (
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
return true;
|
|
469
|
-
} catch (err) {
|
|
470
|
-
if (fileLocked && this.fileLock) {
|
|
471
|
-
await this.fileLock.release(storageKey);
|
|
375
|
+
if (existing) {
|
|
376
|
+
return false;
|
|
472
377
|
}
|
|
473
|
-
throw err;
|
|
474
378
|
}
|
|
379
|
+
await dbRun(
|
|
380
|
+
client,
|
|
381
|
+
`
|
|
382
|
+
INSERT INTO kvcache (key, subKey, value, expiresAt)
|
|
383
|
+
VALUES (?, ?, ?, ?)
|
|
384
|
+
ON CONFLICT(key, subKey) DO UPDATE SET
|
|
385
|
+
value = excluded.value,
|
|
386
|
+
expiresAt = excluded.expiresAt
|
|
387
|
+
`,
|
|
388
|
+
[storageKey, "", this.serialize(value), expiresAt]
|
|
389
|
+
);
|
|
390
|
+
return true;
|
|
475
391
|
}
|
|
476
392
|
async get(key) {
|
|
477
393
|
const client = this.getClient();
|
|
@@ -493,9 +409,6 @@ const _SqliteAdapter = class _SqliteAdapter {
|
|
|
493
409
|
const client = this.getClient();
|
|
494
410
|
const storageKey = this.prefixKey(key);
|
|
495
411
|
await dbRun(client, "DELETE FROM kvcache WHERE key = ?", [storageKey]);
|
|
496
|
-
if (this.fileLock) {
|
|
497
|
-
await this.fileLock.release(storageKey);
|
|
498
|
-
}
|
|
499
412
|
}
|
|
500
413
|
async has(key) {
|
|
501
414
|
const client = this.getClient();
|
|
@@ -572,9 +485,6 @@ const _SqliteAdapter = class _SqliteAdapter {
|
|
|
572
485
|
const client = this.getClient();
|
|
573
486
|
const storageKey = this.prefixKey(key);
|
|
574
487
|
await dbRun(client, "DELETE FROM kvcache WHERE key = ? AND subKey = ?", [storageKey, subKey]);
|
|
575
|
-
if (this.fileLock) {
|
|
576
|
-
await this.fileLock.release(storageKey);
|
|
577
|
-
}
|
|
578
488
|
}
|
|
579
489
|
/* ------------------------------- misc ------------------------------- */
|
|
580
490
|
async close() {
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import path$1 from 'path';
|
|
2
2
|
import { createClient } from 'redis';
|
|
3
3
|
import * as fs from 'node:fs';
|
|
4
|
-
import * as os from 'node:os';
|
|
5
4
|
import * as path from 'node:path';
|
|
6
5
|
import { promisify } from 'node:util';
|
|
7
6
|
import sqlite3 from 'sqlite3';
|
|
8
|
-
import * as crypto from 'node:crypto';
|
|
9
|
-
import lockfile from 'proper-lockfile';
|
|
10
7
|
|
|
11
8
|
function ulid() {
|
|
12
9
|
const alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
@@ -24,20 +21,20 @@ function ulid() {
|
|
|
24
21
|
return timeStr + rand;
|
|
25
22
|
}
|
|
26
23
|
|
|
27
|
-
var __defProp$
|
|
28
|
-
var __defNormalProp$
|
|
29
|
-
var __publicField$
|
|
30
|
-
__defNormalProp$
|
|
24
|
+
var __defProp$4 = Object.defineProperty;
|
|
25
|
+
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
26
|
+
var __publicField$4 = (obj, key, value) => {
|
|
27
|
+
__defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
31
28
|
return value;
|
|
32
29
|
};
|
|
33
30
|
const _RedisAdapter = class _RedisAdapter {
|
|
34
31
|
constructor() {
|
|
35
|
-
__publicField$
|
|
36
|
-
__publicField$
|
|
37
|
-
__publicField$
|
|
38
|
-
__publicField$
|
|
39
|
-
__publicField$
|
|
40
|
-
__publicField$
|
|
32
|
+
__publicField$4(this, "opts", null);
|
|
33
|
+
__publicField$4(this, "defaultTtl", 1e3 * 60 * 60);
|
|
34
|
+
__publicField$4(this, "url", "");
|
|
35
|
+
__publicField$4(this, "prefix", "");
|
|
36
|
+
__publicField$4(this, "prefixKey", (key) => `${this.prefix}:${key}`);
|
|
37
|
+
__publicField$4(this, "prefixKeyGroup", (key) => `${this.prefix}:group:${key}`);
|
|
41
38
|
}
|
|
42
39
|
clearAll() {
|
|
43
40
|
throw new Error("Method not implemented.");
|
|
@@ -182,8 +179,8 @@ const _RedisAdapter = class _RedisAdapter {
|
|
|
182
179
|
}
|
|
183
180
|
};
|
|
184
181
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
185
|
-
__publicField$
|
|
186
|
-
__publicField$
|
|
182
|
+
__publicField$4(_RedisAdapter, "clients", /* @__PURE__ */ new Map());
|
|
183
|
+
__publicField$4(_RedisAdapter, "initPromises", /* @__PURE__ */ new Map());
|
|
187
184
|
let RedisAdapter = _RedisAdapter;
|
|
188
185
|
|
|
189
186
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -212,67 +209,6 @@ async function withRetry(fn, {
|
|
|
212
209
|
}
|
|
213
210
|
}
|
|
214
211
|
|
|
215
|
-
var __defProp$4 = Object.defineProperty;
|
|
216
|
-
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
217
|
-
var __publicField$4 = (obj, key, value) => {
|
|
218
|
-
__defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
219
|
-
return value;
|
|
220
|
-
};
|
|
221
|
-
class FileLock {
|
|
222
|
-
// 默认 10 分钟
|
|
223
|
-
constructor(baseDir, defaultTtl) {
|
|
224
|
-
__publicField$4(this, "baseDir");
|
|
225
|
-
__publicField$4(this, "defaultTtl", 10 * 60 * 1e3);
|
|
226
|
-
this.baseDir = baseDir;
|
|
227
|
-
if (defaultTtl !== void 0) {
|
|
228
|
-
this.defaultTtl = defaultTtl;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
getLockFilePath(storageKey) {
|
|
232
|
-
const lockDir = path.join(this.baseDir, "locks");
|
|
233
|
-
if (!fs.existsSync(lockDir)) {
|
|
234
|
-
fs.mkdirSync(lockDir, { recursive: true });
|
|
235
|
-
}
|
|
236
|
-
const safeName = crypto.createHash("sha256").update(storageKey).digest("hex");
|
|
237
|
-
return path.join(lockDir, `${safeName}.lock`);
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* acquire 返回 true 代表成功加锁
|
|
241
|
-
* 返回 false 代表有其他进程/线程持有锁
|
|
242
|
-
*/
|
|
243
|
-
async acquire(storageKey, ttl) {
|
|
244
|
-
const lockPath = this.getLockFilePath(storageKey);
|
|
245
|
-
const effectiveTtl = ttl !== void 0 ? ttl : this.defaultTtl;
|
|
246
|
-
try {
|
|
247
|
-
try {
|
|
248
|
-
fs.writeFileSync(lockPath, "", { flag: "wx" });
|
|
249
|
-
} catch (_createErr) {
|
|
250
|
-
}
|
|
251
|
-
await lockfile.lock(lockPath, {
|
|
252
|
-
realpath: true,
|
|
253
|
-
stale: effectiveTtl,
|
|
254
|
-
// 超时自动释放
|
|
255
|
-
update: Math.floor(effectiveTtl / 3),
|
|
256
|
-
// 定期续租,避免长任务过期
|
|
257
|
-
retries: 0
|
|
258
|
-
});
|
|
259
|
-
return true;
|
|
260
|
-
} catch (_err) {
|
|
261
|
-
return false;
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* 释放锁
|
|
266
|
-
*/
|
|
267
|
-
async release(storageKey) {
|
|
268
|
-
const lockPath = this.getLockFilePath(storageKey);
|
|
269
|
-
try {
|
|
270
|
-
await lockfile.unlock(lockPath);
|
|
271
|
-
} catch (_err) {
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
212
|
var __defProp$3 = Object.defineProperty;
|
|
277
213
|
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
278
214
|
var __publicField$3 = (obj, key, value) => {
|
|
@@ -338,21 +274,20 @@ const _SqliteAdapter = class _SqliteAdapter {
|
|
|
338
274
|
__publicField$3(this, "defaultTtl", 1e3 * 60 * 60);
|
|
339
275
|
__publicField$3(this, "cleanupInterval", 5 * 60 * 1e3);
|
|
340
276
|
__publicField$3(this, "dbPath", "");
|
|
341
|
-
__publicField$3(this, "fileLock", null);
|
|
342
277
|
}
|
|
343
278
|
/* ------------------------------- init ------------------------------- */
|
|
344
279
|
async ensure() {
|
|
280
|
+
const isMemory = this.opts.sqlitePath === ":memory:";
|
|
345
281
|
if (!this.dbPath) {
|
|
346
|
-
this.dbPath =
|
|
282
|
+
this.dbPath = isMemory ? ":memory:" : path.resolve(this.opts.sqlitePath);
|
|
347
283
|
this.prefix = this.opts.prefix;
|
|
348
284
|
this.defaultTtl = this.opts.ttl;
|
|
349
|
-
this.cleanupInterval = this.opts.cleanupInterval ??
|
|
350
|
-
this.fileLock = new FileLock(os.tmpdir());
|
|
285
|
+
this.cleanupInterval = this.opts.cleanupInterval ?? 5 * 60 * 1e3;
|
|
351
286
|
}
|
|
352
287
|
if (_SqliteAdapter.clients.has(this.dbPath))
|
|
353
288
|
return;
|
|
354
289
|
if (!_SqliteAdapter.initPromises.has(this.dbPath)) {
|
|
355
|
-
if (
|
|
290
|
+
if (!isMemory) {
|
|
356
291
|
const dir = path.dirname(this.dbPath);
|
|
357
292
|
if (!fs.existsSync(dir)) {
|
|
358
293
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -410,44 +345,28 @@ const _SqliteAdapter = class _SqliteAdapter {
|
|
|
410
345
|
const storageKey = this.prefixKey(key);
|
|
411
346
|
const effectiveTtl = opts.ttl !== void 0 ? opts.ttl : this.defaultTtl;
|
|
412
347
|
const expiresAt = effectiveTtl > 0 ? Date.now() + effectiveTtl : null;
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
fileLocked = await this.fileLock.acquire(storageKey, effectiveTtl);
|
|
416
|
-
if (!fileLocked)
|
|
417
|
-
return false;
|
|
418
|
-
}
|
|
419
|
-
try {
|
|
420
|
-
if (opts.nx) {
|
|
421
|
-
const existing = await dbGet(
|
|
422
|
-
client,
|
|
423
|
-
"SELECT value FROM kvcache WHERE key = ? AND subKey = ?",
|
|
424
|
-
[storageKey, ""]
|
|
425
|
-
);
|
|
426
|
-
if (existing) {
|
|
427
|
-
return false;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
await dbRun(
|
|
348
|
+
if (opts.nx) {
|
|
349
|
+
const existing = await dbGet(
|
|
431
350
|
client,
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
VALUES (?, ?, ?, ?)
|
|
435
|
-
ON CONFLICT(key, subKey) DO UPDATE SET
|
|
436
|
-
value = excluded.value,
|
|
437
|
-
expiresAt = excluded.expiresAt
|
|
438
|
-
`,
|
|
439
|
-
[storageKey, "", this.serialize(value), expiresAt]
|
|
351
|
+
"SELECT value FROM kvcache WHERE key = ? AND subKey = ?",
|
|
352
|
+
[storageKey, ""]
|
|
440
353
|
);
|
|
441
|
-
if (
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
return true;
|
|
445
|
-
} catch (err) {
|
|
446
|
-
if (fileLocked && this.fileLock) {
|
|
447
|
-
await this.fileLock.release(storageKey);
|
|
354
|
+
if (existing) {
|
|
355
|
+
return false;
|
|
448
356
|
}
|
|
449
|
-
throw err;
|
|
450
357
|
}
|
|
358
|
+
await dbRun(
|
|
359
|
+
client,
|
|
360
|
+
`
|
|
361
|
+
INSERT INTO kvcache (key, subKey, value, expiresAt)
|
|
362
|
+
VALUES (?, ?, ?, ?)
|
|
363
|
+
ON CONFLICT(key, subKey) DO UPDATE SET
|
|
364
|
+
value = excluded.value,
|
|
365
|
+
expiresAt = excluded.expiresAt
|
|
366
|
+
`,
|
|
367
|
+
[storageKey, "", this.serialize(value), expiresAt]
|
|
368
|
+
);
|
|
369
|
+
return true;
|
|
451
370
|
}
|
|
452
371
|
async get(key) {
|
|
453
372
|
const client = this.getClient();
|
|
@@ -469,9 +388,6 @@ const _SqliteAdapter = class _SqliteAdapter {
|
|
|
469
388
|
const client = this.getClient();
|
|
470
389
|
const storageKey = this.prefixKey(key);
|
|
471
390
|
await dbRun(client, "DELETE FROM kvcache WHERE key = ?", [storageKey]);
|
|
472
|
-
if (this.fileLock) {
|
|
473
|
-
await this.fileLock.release(storageKey);
|
|
474
|
-
}
|
|
475
391
|
}
|
|
476
392
|
async has(key) {
|
|
477
393
|
const client = this.getClient();
|
|
@@ -548,9 +464,6 @@ const _SqliteAdapter = class _SqliteAdapter {
|
|
|
548
464
|
const client = this.getClient();
|
|
549
465
|
const storageKey = this.prefixKey(key);
|
|
550
466
|
await dbRun(client, "DELETE FROM kvcache WHERE key = ? AND subKey = ?", [storageKey, subKey]);
|
|
551
|
-
if (this.fileLock) {
|
|
552
|
-
await this.fileLock.release(storageKey);
|
|
553
|
-
}
|
|
554
467
|
}
|
|
555
468
|
/* ------------------------------- misc ------------------------------- */
|
|
556
469
|
async close() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abtnode/db-cache",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.4-beta-20251201-095907-eebbbbce",
|
|
4
4
|
"description": "Db cache use redis or sqlite as backend",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"typescript": "^5.6.3",
|
|
43
43
|
"unbuild": "^2.0.0"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "a22171e333c5e1eccd03b9980bac1ae14749735e"
|
|
46
46
|
}
|