keyv-dir-store 0.0.2 → 0.0.4
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/CHANGELOG.md +16 -0
- package/README.md +21 -11
- package/dist/index.js +17 -255
- package/index.test.ts +4 -4
- package/index.ts +14 -15
- package/package.json +7 -6
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
|
+
|
|
5
|
+
### [0.0.4](https://github.com/snomiao/keyv-dir-store/compare/v0.0.3...v0.0.4) (2024-06-26)
|
|
6
|
+
|
|
7
|
+
### [0.0.3](https://github.com/snomiao/keyv-dir-store/compare/v0.0.2...v0.0.3) (2024-06-12)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* **kds:** init ([7ef5f68](https://github.com/snomiao/keyv-dir-store/commit/7ef5f68430657a81dcace597148c7641032ed6ab))
|
|
13
|
+
|
|
14
|
+
### [0.0.2](https://github.com/snomiao/keyv-dir-store/compare/v0.0.1...v0.0.2) (2024-06-12)
|
|
15
|
+
|
|
16
|
+
### 0.0.1 (2024-06-12)
|
package/README.md
CHANGED
|
@@ -1,24 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
# KeyvDIR
|
|
1
|
+
# Keyv Directory Store
|
|
3
2
|
|
|
4
3
|
Store key into a file per value
|
|
5
4
|
|
|
6
|
-
##
|
|
5
|
+
## Usages
|
|
7
6
|
|
|
8
7
|
```ts
|
|
8
|
+
// Default: Store each value with JSON in format "{value: ..., expires: ...}"
|
|
9
9
|
new Keyv({
|
|
10
|
-
store: new KeyvDirStore("cache/kv"
|
|
11
|
-
serialize: ({ value }) => csvFormat(value),
|
|
12
|
-
deserialize: (str) => ({ value: csvParse(str), expires: undefined }),
|
|
10
|
+
store: new KeyvDirStore(".cache/kv")
|
|
13
11
|
});
|
|
14
|
-
```
|
|
15
12
|
|
|
16
|
-
|
|
13
|
+
// Store each value with CSV
|
|
14
|
+
new Keyv({
|
|
15
|
+
store: new KeyvDirStore(".cache/kv", { ext: ".csv" }),
|
|
16
|
+
serialize: ({ value }) => d3.csvFormat(value),
|
|
17
|
+
deserialize: (str) => ({ value: d3.csvParse(str), expires: undefined }),
|
|
18
|
+
});
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
// Store each value with YAML
|
|
19
21
|
new Keyv({
|
|
20
|
-
store: new KeyvDirStore("cache/kv", { ext: "
|
|
22
|
+
store: new KeyvDirStore(".cache/kv", { ext: ".json" }),
|
|
21
23
|
serialize: ({ value }) => yaml.stringify(value),
|
|
22
24
|
deserialize: (str) => ({ value: yaml.parse(str), expires: undefined }),
|
|
23
25
|
});
|
|
24
|
-
|
|
26
|
+
|
|
27
|
+
// Store each value with JSON
|
|
28
|
+
new Keyv({
|
|
29
|
+
store: new KeyvDirStore(".cache/kv", { ext: ".json" }),
|
|
30
|
+
serialize: ({ value }) => JSON.stringify(value, null, 2),
|
|
31
|
+
deserialize: (str) => ({ value: JSON.parse(str), expires: undefined }),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @bun
|
|
1
2
|
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -286,47 +287,10 @@ var require_truncate = __commonJS((exports, module) => {
|
|
|
286
287
|
};
|
|
287
288
|
});
|
|
288
289
|
|
|
289
|
-
// node_modules/utf8-
|
|
290
|
-
var
|
|
291
|
-
var isHighSurrogate = function(codePoint) {
|
|
292
|
-
return codePoint >= 55296 && codePoint <= 56319;
|
|
293
|
-
};
|
|
294
|
-
var isLowSurrogate = function(codePoint) {
|
|
295
|
-
return codePoint >= 56320 && codePoint <= 57343;
|
|
296
|
-
};
|
|
297
|
-
module.exports = function getByteLength(string) {
|
|
298
|
-
if (typeof string !== "string") {
|
|
299
|
-
throw new Error("Input must be string");
|
|
300
|
-
}
|
|
301
|
-
var charLength = string.length;
|
|
302
|
-
var byteLength = 0;
|
|
303
|
-
var codePoint = null;
|
|
304
|
-
var prevCodePoint = null;
|
|
305
|
-
for (var i = 0;i < charLength; i++) {
|
|
306
|
-
codePoint = string.charCodeAt(i);
|
|
307
|
-
if (isLowSurrogate(codePoint)) {
|
|
308
|
-
if (prevCodePoint != null && isHighSurrogate(prevCodePoint)) {
|
|
309
|
-
byteLength += 1;
|
|
310
|
-
} else {
|
|
311
|
-
byteLength += 3;
|
|
312
|
-
}
|
|
313
|
-
} else if (codePoint <= 127) {
|
|
314
|
-
byteLength += 1;
|
|
315
|
-
} else if (codePoint >= 128 && codePoint <= 2047) {
|
|
316
|
-
byteLength += 2;
|
|
317
|
-
} else if (codePoint >= 2048 && codePoint <= 65535) {
|
|
318
|
-
byteLength += 3;
|
|
319
|
-
}
|
|
320
|
-
prevCodePoint = codePoint;
|
|
321
|
-
}
|
|
322
|
-
return byteLength;
|
|
323
|
-
};
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
// node_modules/truncate-utf8-bytes/browser.js
|
|
327
|
-
var require_browser2 = __commonJS((exports, module) => {
|
|
290
|
+
// node_modules/truncate-utf8-bytes/index.js
|
|
291
|
+
var require_truncate_utf8_bytes = __commonJS((exports, module) => {
|
|
328
292
|
var truncate = require_truncate();
|
|
329
|
-
var getLength =
|
|
293
|
+
var getLength = Buffer.byteLength.bind(Buffer);
|
|
330
294
|
module.exports = truncate.bind(null, getLength);
|
|
331
295
|
});
|
|
332
296
|
|
|
@@ -339,7 +303,7 @@ var require_sanitize_filename = __commonJS((exports, module) => {
|
|
|
339
303
|
var sanitized = input.replace(illegalRe, replacement).replace(controlRe, replacement).replace(reservedRe, replacement).replace(windowsReservedRe, replacement).replace(windowsTrailingRe, replacement);
|
|
340
304
|
return truncate(sanitized, 255);
|
|
341
305
|
};
|
|
342
|
-
var truncate =
|
|
306
|
+
var truncate = require_truncate_utf8_bytes();
|
|
343
307
|
var illegalRe = /[\/\?<>\\:\*\|"]/g;
|
|
344
308
|
var controlRe = /[\x00-\x1f\x80-\x9f]/g;
|
|
345
309
|
var reservedRe = /^\.+$/;
|
|
@@ -358,236 +322,34 @@ var require_sanitize_filename = __commonJS((exports, module) => {
|
|
|
358
322
|
// index.ts
|
|
359
323
|
var import_md5 = __toESM(require_md5(), 1);
|
|
360
324
|
var import_sanitize_filename = __toESM(require_sanitize_filename(), 1);
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
var {rm} = (()=>({}));
|
|
364
|
-
var {readFile, mkdir} = (()=>({}));
|
|
365
|
-
|
|
366
|
-
// node:path
|
|
367
|
-
var L = Object.create;
|
|
368
|
-
var b = Object.defineProperty;
|
|
369
|
-
var z = Object.getOwnPropertyDescriptor;
|
|
370
|
-
var D = Object.getOwnPropertyNames;
|
|
371
|
-
var T = Object.getPrototypeOf;
|
|
372
|
-
var R = Object.prototype.hasOwnProperty;
|
|
373
|
-
var _ = (f, e) => () => (e || f((e = { exports: {} }).exports, e), e.exports);
|
|
374
|
-
var E = (f, e) => {
|
|
375
|
-
for (var r in e)
|
|
376
|
-
b(f, r, { get: e[r], enumerable: true });
|
|
377
|
-
};
|
|
378
|
-
var C = (f, e, r, l) => {
|
|
379
|
-
if (e && typeof e == "object" || typeof e == "function")
|
|
380
|
-
for (let i of D(e))
|
|
381
|
-
!R.call(f, i) && i !== r && b(f, i, { get: () => e[i], enumerable: !(l = z(e, i)) || l.enumerable });
|
|
382
|
-
return f;
|
|
383
|
-
};
|
|
384
|
-
var A = (f, e, r) => (C(f, e, "default"), r && C(r, e, "default"));
|
|
385
|
-
var y = (f, e, r) => (r = f != null ? L(T(f)) : {}, C(e || !f || !f.__esModule ? b(r, "default", { value: f, enumerable: true }) : r, f));
|
|
386
|
-
var h = _((F, S) => {
|
|
387
|
-
function c(f) {
|
|
388
|
-
if (typeof f != "string")
|
|
389
|
-
throw new TypeError("Path must be a string. Received " + JSON.stringify(f));
|
|
390
|
-
}
|
|
391
|
-
function w(f, e) {
|
|
392
|
-
for (var r = "", l = 0, i = -1, s = 0, n, t = 0;t <= f.length; ++t) {
|
|
393
|
-
if (t < f.length)
|
|
394
|
-
n = f.charCodeAt(t);
|
|
395
|
-
else {
|
|
396
|
-
if (n === 47)
|
|
397
|
-
break;
|
|
398
|
-
n = 47;
|
|
399
|
-
}
|
|
400
|
-
if (n === 47) {
|
|
401
|
-
if (!(i === t - 1 || s === 1))
|
|
402
|
-
if (i !== t - 1 && s === 2) {
|
|
403
|
-
if (r.length < 2 || l !== 2 || r.charCodeAt(r.length - 1) !== 46 || r.charCodeAt(r.length - 2) !== 46) {
|
|
404
|
-
if (r.length > 2) {
|
|
405
|
-
var a = r.lastIndexOf("/");
|
|
406
|
-
if (a !== r.length - 1) {
|
|
407
|
-
a === -1 ? (r = "", l = 0) : (r = r.slice(0, a), l = r.length - 1 - r.lastIndexOf("/")), i = t, s = 0;
|
|
408
|
-
continue;
|
|
409
|
-
}
|
|
410
|
-
} else if (r.length === 2 || r.length === 1) {
|
|
411
|
-
r = "", l = 0, i = t, s = 0;
|
|
412
|
-
continue;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
e && (r.length > 0 ? r += "/.." : r = "..", l = 2);
|
|
416
|
-
} else
|
|
417
|
-
r.length > 0 ? r += "/" + f.slice(i + 1, t) : r = f.slice(i + 1, t), l = t - i - 1;
|
|
418
|
-
i = t, s = 0;
|
|
419
|
-
} else
|
|
420
|
-
n === 46 && s !== -1 ? ++s : s = -1;
|
|
421
|
-
}
|
|
422
|
-
return r;
|
|
423
|
-
}
|
|
424
|
-
function J(f, e) {
|
|
425
|
-
var r = e.dir || e.root, l = e.base || (e.name || "") + (e.ext || "");
|
|
426
|
-
return r ? r === e.root ? r + l : r + f + l : l;
|
|
427
|
-
}
|
|
428
|
-
var g = { resolve: function() {
|
|
429
|
-
for (var e = "", r = false, l, i = arguments.length - 1;i >= -1 && !r; i--) {
|
|
430
|
-
var s;
|
|
431
|
-
i >= 0 ? s = arguments[i] : (l === undefined && (l = process.cwd()), s = l), c(s), s.length !== 0 && (e = s + "/" + e, r = s.charCodeAt(0) === 47);
|
|
432
|
-
}
|
|
433
|
-
return e = w(e, !r), r ? e.length > 0 ? "/" + e : "/" : e.length > 0 ? e : ".";
|
|
434
|
-
}, normalize: function(e) {
|
|
435
|
-
if (c(e), e.length === 0)
|
|
436
|
-
return ".";
|
|
437
|
-
var r = e.charCodeAt(0) === 47, l = e.charCodeAt(e.length - 1) === 47;
|
|
438
|
-
return e = w(e, !r), e.length === 0 && !r && (e = "."), e.length > 0 && l && (e += "/"), r ? "/" + e : e;
|
|
439
|
-
}, isAbsolute: function(e) {
|
|
440
|
-
return c(e), e.length > 0 && e.charCodeAt(0) === 47;
|
|
441
|
-
}, join: function() {
|
|
442
|
-
if (arguments.length === 0)
|
|
443
|
-
return ".";
|
|
444
|
-
for (var e, r = 0;r < arguments.length; ++r) {
|
|
445
|
-
var l = arguments[r];
|
|
446
|
-
c(l), l.length > 0 && (e === undefined ? e = l : e += "/" + l);
|
|
447
|
-
}
|
|
448
|
-
return e === undefined ? "." : g.normalize(e);
|
|
449
|
-
}, relative: function(e, r) {
|
|
450
|
-
if (c(e), c(r), e === r || (e = g.resolve(e), r = g.resolve(r), e === r))
|
|
451
|
-
return "";
|
|
452
|
-
for (var l = 1;l < e.length && e.charCodeAt(l) === 47; ++l)
|
|
453
|
-
;
|
|
454
|
-
for (var i = e.length, s = i - l, n = 1;n < r.length && r.charCodeAt(n) === 47; ++n)
|
|
455
|
-
;
|
|
456
|
-
for (var t = r.length, a = t - n, v = s < a ? s : a, u = -1, o = 0;o <= v; ++o) {
|
|
457
|
-
if (o === v) {
|
|
458
|
-
if (a > v) {
|
|
459
|
-
if (r.charCodeAt(n + o) === 47)
|
|
460
|
-
return r.slice(n + o + 1);
|
|
461
|
-
if (o === 0)
|
|
462
|
-
return r.slice(n + o);
|
|
463
|
-
} else
|
|
464
|
-
s > v && (e.charCodeAt(l + o) === 47 ? u = o : o === 0 && (u = 0));
|
|
465
|
-
break;
|
|
466
|
-
}
|
|
467
|
-
var k = e.charCodeAt(l + o), P = r.charCodeAt(n + o);
|
|
468
|
-
if (k !== P)
|
|
469
|
-
break;
|
|
470
|
-
k === 47 && (u = o);
|
|
471
|
-
}
|
|
472
|
-
var d = "";
|
|
473
|
-
for (o = l + u + 1;o <= i; ++o)
|
|
474
|
-
(o === i || e.charCodeAt(o) === 47) && (d.length === 0 ? d += ".." : d += "/..");
|
|
475
|
-
return d.length > 0 ? d + r.slice(n + u) : (n += u, r.charCodeAt(n) === 47 && ++n, r.slice(n));
|
|
476
|
-
}, _makeLong: function(e) {
|
|
477
|
-
return e;
|
|
478
|
-
}, dirname: function(e) {
|
|
479
|
-
if (c(e), e.length === 0)
|
|
480
|
-
return ".";
|
|
481
|
-
for (var r = e.charCodeAt(0), l = r === 47, i = -1, s = true, n = e.length - 1;n >= 1; --n)
|
|
482
|
-
if (r = e.charCodeAt(n), r === 47) {
|
|
483
|
-
if (!s) {
|
|
484
|
-
i = n;
|
|
485
|
-
break;
|
|
486
|
-
}
|
|
487
|
-
} else
|
|
488
|
-
s = false;
|
|
489
|
-
return i === -1 ? l ? "/" : "." : l && i === 1 ? "//" : e.slice(0, i);
|
|
490
|
-
}, basename: function(e, r) {
|
|
491
|
-
if (r !== undefined && typeof r != "string")
|
|
492
|
-
throw new TypeError('"ext" argument must be a string');
|
|
493
|
-
c(e);
|
|
494
|
-
var l = 0, i = -1, s = true, n;
|
|
495
|
-
if (r !== undefined && r.length > 0 && r.length <= e.length) {
|
|
496
|
-
if (r.length === e.length && r === e)
|
|
497
|
-
return "";
|
|
498
|
-
var t = r.length - 1, a = -1;
|
|
499
|
-
for (n = e.length - 1;n >= 0; --n) {
|
|
500
|
-
var v = e.charCodeAt(n);
|
|
501
|
-
if (v === 47) {
|
|
502
|
-
if (!s) {
|
|
503
|
-
l = n + 1;
|
|
504
|
-
break;
|
|
505
|
-
}
|
|
506
|
-
} else
|
|
507
|
-
a === -1 && (s = false, a = n + 1), t >= 0 && (v === r.charCodeAt(t) ? --t === -1 && (i = n) : (t = -1, i = a));
|
|
508
|
-
}
|
|
509
|
-
return l === i ? i = a : i === -1 && (i = e.length), e.slice(l, i);
|
|
510
|
-
} else {
|
|
511
|
-
for (n = e.length - 1;n >= 0; --n)
|
|
512
|
-
if (e.charCodeAt(n) === 47) {
|
|
513
|
-
if (!s) {
|
|
514
|
-
l = n + 1;
|
|
515
|
-
break;
|
|
516
|
-
}
|
|
517
|
-
} else
|
|
518
|
-
i === -1 && (s = false, i = n + 1);
|
|
519
|
-
return i === -1 ? "" : e.slice(l, i);
|
|
520
|
-
}
|
|
521
|
-
}, extname: function(e) {
|
|
522
|
-
c(e);
|
|
523
|
-
for (var r = -1, l = 0, i = -1, s = true, n = 0, t = e.length - 1;t >= 0; --t) {
|
|
524
|
-
var a = e.charCodeAt(t);
|
|
525
|
-
if (a === 47) {
|
|
526
|
-
if (!s) {
|
|
527
|
-
l = t + 1;
|
|
528
|
-
break;
|
|
529
|
-
}
|
|
530
|
-
continue;
|
|
531
|
-
}
|
|
532
|
-
i === -1 && (s = false, i = t + 1), a === 46 ? r === -1 ? r = t : n !== 1 && (n = 1) : r !== -1 && (n = -1);
|
|
533
|
-
}
|
|
534
|
-
return r === -1 || i === -1 || n === 0 || n === 1 && r === i - 1 && r === l + 1 ? "" : e.slice(r, i);
|
|
535
|
-
}, format: function(e) {
|
|
536
|
-
if (e === null || typeof e != "object")
|
|
537
|
-
throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof e);
|
|
538
|
-
return J("/", e);
|
|
539
|
-
}, parse: function(e) {
|
|
540
|
-
c(e);
|
|
541
|
-
var r = { root: "", dir: "", base: "", ext: "", name: "" };
|
|
542
|
-
if (e.length === 0)
|
|
543
|
-
return r;
|
|
544
|
-
var l = e.charCodeAt(0), i = l === 47, s;
|
|
545
|
-
i ? (r.root = "/", s = 1) : s = 0;
|
|
546
|
-
for (var n = -1, t = 0, a = -1, v = true, u = e.length - 1, o = 0;u >= s; --u) {
|
|
547
|
-
if (l = e.charCodeAt(u), l === 47) {
|
|
548
|
-
if (!v) {
|
|
549
|
-
t = u + 1;
|
|
550
|
-
break;
|
|
551
|
-
}
|
|
552
|
-
continue;
|
|
553
|
-
}
|
|
554
|
-
a === -1 && (v = false, a = u + 1), l === 46 ? n === -1 ? n = u : o !== 1 && (o = 1) : n !== -1 && (o = -1);
|
|
555
|
-
}
|
|
556
|
-
return n === -1 || a === -1 || o === 0 || o === 1 && n === a - 1 && n === t + 1 ? a !== -1 && (t === 0 && i ? r.base = r.name = e.slice(1, a) : r.base = r.name = e.slice(t, a)) : (t === 0 && i ? (r.name = e.slice(1, n), r.base = e.slice(1, a)) : (r.name = e.slice(t, n), r.base = e.slice(t, a)), r.ext = e.slice(n, a)), t > 0 ? r.dir = e.slice(0, t - 1) : i && (r.dir = "/"), r;
|
|
557
|
-
}, sep: "/", delimiter: ":", win32: null, posix: null };
|
|
558
|
-
g.posix = g;
|
|
559
|
-
S.exports = g;
|
|
560
|
-
});
|
|
561
|
-
var m = {};
|
|
562
|
-
E(m, { default: () => q });
|
|
563
|
-
A(m, y(h()));
|
|
564
|
-
var q = y(h());
|
|
565
|
-
|
|
566
|
-
// index.ts
|
|
567
|
-
var {utimes} = (()=>({}));
|
|
325
|
+
import {mkdir, readFile, rm, stat, utimes, writeFile} from "fs/promises";
|
|
326
|
+
import path from "path";
|
|
568
327
|
|
|
569
328
|
class KeyvDirStore {
|
|
570
329
|
#dir;
|
|
571
330
|
#cache;
|
|
572
331
|
#ready;
|
|
573
|
-
#
|
|
332
|
+
#filename;
|
|
574
333
|
ext = ".json";
|
|
575
334
|
constructor(dir, {
|
|
576
335
|
cache = new Map,
|
|
577
|
-
|
|
336
|
+
filename,
|
|
578
337
|
ext
|
|
579
338
|
} = {}) {
|
|
580
339
|
this.#ready = mkdir(dir, { recursive: true });
|
|
581
340
|
this.#cache = cache;
|
|
582
341
|
this.#dir = dir;
|
|
583
|
-
this.#
|
|
342
|
+
this.#filename = filename ?? this.#defaultFilename;
|
|
584
343
|
this.ext = ext ?? this.ext;
|
|
585
344
|
}
|
|
586
|
-
#
|
|
345
|
+
#defaultFilename(key) {
|
|
587
346
|
const readableName = import_sanitize_filename.default(key).slice(4, 16);
|
|
588
|
-
const hashName = import_md5.default(
|
|
589
|
-
const name = readableName
|
|
590
|
-
return
|
|
347
|
+
const hashName = import_md5.default(key + "+SALT-poS1djRa4M2jXsWi").slice(0, 16);
|
|
348
|
+
const name = `${readableName}-${hashName}`;
|
|
349
|
+
return name;
|
|
350
|
+
}
|
|
351
|
+
#path(key) {
|
|
352
|
+
return path.join(this.#dir, this.#filename(key) + this.ext);
|
|
591
353
|
}
|
|
592
354
|
async get(key) {
|
|
593
355
|
const cached = this.#cache.get(key);
|
package/index.test.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { KeyvDirStore } from ".";
|
|
|
4
4
|
it("KeyvDirStore works", async () => {
|
|
5
5
|
// store test
|
|
6
6
|
const kv = new Keyv<number | string | { obj: boolean }>({
|
|
7
|
-
store: new KeyvDirStore("cache/test1"),
|
|
7
|
+
store: new KeyvDirStore(".cache/test1"),
|
|
8
8
|
deserialize: KeyvDirStore.deserialize,
|
|
9
9
|
serialize: KeyvDirStore.serialize,
|
|
10
10
|
});
|
|
@@ -20,7 +20,7 @@ it("KeyvDirStore works", async () => {
|
|
|
20
20
|
|
|
21
21
|
// new instance with no cache Obj, to test file cache
|
|
22
22
|
const kv2 = new Keyv<number | string | { obj: boolean }>({
|
|
23
|
-
store: new KeyvDirStore("cache/test1"),
|
|
23
|
+
store: new KeyvDirStore(".cache/test1"),
|
|
24
24
|
deserialize: KeyvDirStore.deserialize,
|
|
25
25
|
serialize: KeyvDirStore.serialize,
|
|
26
26
|
});
|
|
@@ -32,7 +32,7 @@ it("KeyvDirStore works", async () => {
|
|
|
32
32
|
it("KeyvDirStore works with only store", async () => {
|
|
33
33
|
// store test
|
|
34
34
|
const kv = new Keyv<number | string | { obj: boolean }>({
|
|
35
|
-
store: new KeyvDirStore("cache/test2"),
|
|
35
|
+
store: new KeyvDirStore(".cache/test2"),
|
|
36
36
|
});
|
|
37
37
|
await kv.clear();
|
|
38
38
|
await kv.set("a", 1234, -86400e3); // already expired
|
|
@@ -46,7 +46,7 @@ it("KeyvDirStore works with only store", async () => {
|
|
|
46
46
|
|
|
47
47
|
// new instance with no cache Obj, to test file cache
|
|
48
48
|
const kv2 = new Keyv<number | string | { obj: boolean }>({
|
|
49
|
-
store: new KeyvDirStore("cache/test2"),
|
|
49
|
+
store: new KeyvDirStore(".cache/test2"),
|
|
50
50
|
});
|
|
51
51
|
expect(await kv2.get("a")).toEqual(undefined); // will delete file before get
|
|
52
52
|
expect(await kv2.get("b")).toEqual(1234);
|
package/index.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { writeFile } from "fs/promises";
|
|
3
|
-
import { rm } from "fs/promises";
|
|
4
|
-
import { readFile, mkdir } from "fs/promises";
|
|
5
|
-
import { type default as Keyv, type DeserializedData } from "keyv";
|
|
1
|
+
import type { DeserializedData, default as Keyv } from "keyv";
|
|
6
2
|
import md5 from "md5";
|
|
7
|
-
import
|
|
3
|
+
import { mkdir, readFile, rm, stat, utimes, writeFile } from "node:fs/promises";
|
|
8
4
|
import path from "path";
|
|
9
|
-
import
|
|
5
|
+
import sanitizeFilename from "sanitize-filename";
|
|
10
6
|
type Value = any;
|
|
11
7
|
type CacheMap<Value> = Map<string, DeserializedData<Value>>;
|
|
12
8
|
/**
|
|
@@ -26,32 +22,35 @@ export class KeyvDirStore implements Keyv.Store<string> {
|
|
|
26
22
|
#dir: string;
|
|
27
23
|
#cache: CacheMap<Value>;
|
|
28
24
|
#ready: Promise<unknown>;
|
|
29
|
-
#
|
|
25
|
+
#filename: (key: string) => string;
|
|
30
26
|
ext = ".json";
|
|
31
27
|
constructor(
|
|
32
28
|
dir: string,
|
|
33
29
|
{
|
|
34
30
|
cache = new Map(),
|
|
35
|
-
|
|
31
|
+
filename,
|
|
36
32
|
ext,
|
|
37
33
|
}: {
|
|
38
34
|
cache?: CacheMap<Value>;
|
|
39
|
-
|
|
35
|
+
filename?: (key: string) => string;
|
|
40
36
|
ext?: string;
|
|
41
37
|
} = {}
|
|
42
38
|
) {
|
|
43
39
|
this.#ready = mkdir(dir, { recursive: true });
|
|
44
40
|
this.#cache = cache;
|
|
45
41
|
this.#dir = dir;
|
|
46
|
-
this.#
|
|
42
|
+
this.#filename = filename ?? this.#defaultFilename;
|
|
47
43
|
this.ext = ext ?? this.ext;
|
|
48
44
|
}
|
|
49
|
-
#
|
|
45
|
+
#defaultFilename(key: string) {
|
|
50
46
|
// use dir as hash salt to avoid collisions
|
|
51
47
|
const readableName = sanitizeFilename(key).slice(4, 16);
|
|
52
|
-
const hashName = md5(
|
|
53
|
-
const name = readableName
|
|
54
|
-
return
|
|
48
|
+
const hashName = md5(key + "+SALT-poS1djRa4M2jXsWi").slice(0, 16);
|
|
49
|
+
const name = `${readableName}-${hashName}`;
|
|
50
|
+
return name;
|
|
51
|
+
}
|
|
52
|
+
#path(key: string) {
|
|
53
|
+
return path.join(this.#dir, this.#filename(key) + this.ext);
|
|
55
54
|
}
|
|
56
55
|
async get(key: string) {
|
|
57
56
|
// read memory
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keyv-dir-store",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"author": "snomiao <snomiao@gmail.com>",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -13,11 +13,16 @@
|
|
|
13
13
|
"dist"
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
|
-
"build": "bun build index.ts --outdir=dist",
|
|
16
|
+
"build": "bun build index.ts --outdir=dist --target=bun",
|
|
17
17
|
"prerelease": "bun run build && bun run test",
|
|
18
18
|
"release": "bunx standard-version && git push --follow-tags && npm publish",
|
|
19
19
|
"test": "bun test"
|
|
20
20
|
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@types/node": "^20.14.2",
|
|
23
|
+
"md5": "^2.3.0",
|
|
24
|
+
"sanitize-filename": "^1.6.3"
|
|
25
|
+
},
|
|
21
26
|
"devDependencies": {
|
|
22
27
|
"@types/bun": "^1.1.3",
|
|
23
28
|
"@types/jest": "^29.5.12",
|
|
@@ -26,9 +31,5 @@
|
|
|
26
31
|
},
|
|
27
32
|
"peerDependencies": {
|
|
28
33
|
"keyv": "^4.5.4"
|
|
29
|
-
},
|
|
30
|
-
"dependencies": {
|
|
31
|
-
"md5": "^2.3.0",
|
|
32
|
-
"sanitize-filename": "^1.6.3"
|
|
33
34
|
}
|
|
34
35
|
}
|