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 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
- ## Store each value with CSV
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", { ext: "csv" }),
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
- ## Store each value with YAML
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
- ```ts
20
+ // Store each value with YAML
19
21
  new Keyv({
20
- store: new KeyvDirStore("cache/kv", { ext: "yaml" }),
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-byte-length/browser.js
290
- var require_browser = __commonJS((exports, module) => {
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 = require_browser();
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 = require_browser2();
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
- var {stat} = (()=>({}));
362
- var {writeFile} = (()=>({}));
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
- #path;
332
+ #filename;
574
333
  ext = ".json";
575
334
  constructor(dir, {
576
335
  cache = new Map,
577
- path,
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.#path = path ?? this.#defaultPath;
342
+ this.#filename = filename ?? this.#defaultFilename;
584
343
  this.ext = ext ?? this.ext;
585
344
  }
586
- #defaultPath(key) {
345
+ #defaultFilename(key) {
587
346
  const readableName = import_sanitize_filename.default(key).slice(4, 16);
588
- const hashName = import_md5.default(this.#dir + key).slice(0, 16);
589
- const name = readableName + "-" + hashName + this.ext;
590
- return q.join(this.#dir, name);
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 { stat } from "fs/promises";
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 sanitizeFilename from "sanitize-filename";
3
+ import { mkdir, readFile, rm, stat, utimes, writeFile } from "node:fs/promises";
8
4
  import path from "path";
9
- import { utimes } from "fs/promises";
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
- #path: (key: string) => string;
25
+ #filename: (key: string) => string;
30
26
  ext = ".json";
31
27
  constructor(
32
28
  dir: string,
33
29
  {
34
30
  cache = new Map(),
35
- path,
31
+ filename,
36
32
  ext,
37
33
  }: {
38
34
  cache?: CacheMap<Value>;
39
- path?: (key: string) => string;
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.#path = path ?? this.#defaultPath;
42
+ this.#filename = filename ?? this.#defaultFilename;
47
43
  this.ext = ext ?? this.ext;
48
44
  }
49
- #defaultPath(key: string) {
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(this.#dir + key).slice(0, 16);
53
- const name = readableName + "-" + hashName + this.ext;
54
- return path.join(this.#dir, name);
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.2",
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
  }