@e280/mammoth 0.1.0-5 → 0.1.0-6

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 CHANGED
@@ -74,9 +74,9 @@ const mammoth = new Mammoth()
74
74
  ```ts
75
75
  const exists = await mammoth.has(hash)
76
76
  ```
77
- - **get file size,** in bytes.
77
+ - **get file info,** including size in bytes, added timestamp, and bucket id.
78
78
  ```ts
79
- const size = await mammoth.size(hash)
79
+ const {size, added, id} = await mammoth.info(hash)
80
80
  ```
81
81
  - **get stats,** for the whole datalake.
82
82
  ```ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e280/mammoth",
3
- "version": "0.1.0-5",
3
+ "version": "0.1.0-6",
4
4
  "description": "big file storage",
5
5
  "license": "MIT",
6
6
  "author": "Chase Moskal <chasemoskal@gmail.com>",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@e280/kv": "^0.1.5",
27
- "@e280/stz": "^0.3.4",
27
+ "@e280/stz": "^0.3.5",
28
28
  "@noble/hashes": "^2.2.0"
29
29
  },
30
30
  "devDependencies": {
@@ -20,12 +20,6 @@ export class OpfsBucket implements Bucket {
20
20
  }
21
21
  }
22
22
 
23
- async size(id: Id) {
24
- const handle = await this.#directory.getFileHandle(id)
25
- const file = await handle.getFile()
26
- return file.size
27
- }
28
-
29
23
  async delete(id: Id) {
30
24
  try {
31
25
  await this.#directory.removeEntry(id)
@@ -0,0 +1,9 @@
1
+
2
+ import {time} from "@e280/stz"
3
+
4
+ export const consts = {
5
+ max_jobs: 64,
6
+ self_clean_limit: 64,
7
+ expiry_time: time.days(7),
8
+ }
9
+
package/s/core/mammoth.ts CHANGED
@@ -1,100 +1,82 @@
1
1
 
2
2
  import {Kv} from "@e280/kv"
3
- import {collect, got, queue} from "@e280/stz"
3
+ import {lane, queue} from "@e280/stz"
4
4
 
5
+ import {consts} from "./consts.js"
6
+ import {Hash, Bucket} from "./types.js"
7
+ import {Manifest} from "./utils/manifest.js"
5
8
  import {randomId} from "./utils/random-id.js"
6
- import {notFound} from "./utils/not-found.js"
7
9
  import {MemoryBucket} from "./memory-bucket.js"
8
- import {isExpired} from "./utils/is-expired.js"
9
10
  import {saveAndHash} from "./utils/save-and-hash.js"
10
- import {Hash, Bucket, Id, Stats, Wip} from "./types.js"
11
11
 
12
12
  /** file storage datalake, content-addressed with blake3 hashes. */
13
13
  export class Mammoth {
14
- #ids // associates file hashes with bucket ids
15
- #wip // temporary record of writes in-progress
16
- #stats // statistics about the whole datalake
17
- #bucket // file blobstore
14
+ #bucket
15
+ #manifest
16
+ #wholesome = lane(consts.max_jobs)
18
17
 
19
18
  constructor(bucket: Bucket = new MemoryBucket(), kv = new Kv()) {
20
- this.#ids = kv.scope<string>("ids")
21
- this.#wip = kv.scope<Wip>("wip")
22
- this.#stats = kv.store<Stats>("stats")
23
19
  this.#bucket = bucket
20
+ this.#manifest = new Manifest(kv)
24
21
  }
25
22
 
26
23
  async has(hash: Hash) {
27
- return this.#ids.has(hash)
24
+ return this.#manifest.hasHash(hash)
28
25
  }
29
26
 
30
- async size(hash: Hash) {
31
- const id = got(await this.#ids.get(hash), notFound(hash))
32
- return this.#bucket.size(id)
27
+ async info(hash: Hash) {
28
+ return this.#manifest.needInfo(hash)
33
29
  }
34
30
 
35
31
  async read(hash: Hash) {
36
- const id = got(await this.#ids.get(hash), notFound(hash))
32
+ const {id} = await this.#manifest.needInfo(hash)
37
33
  return this.#bucket.read(id)
38
34
  }
39
35
 
40
36
  async delete(hash: Hash) {
41
- const id = await this.#ids.get(hash)
42
- if (id) {
43
- const size = await this.#bucket.size(id)
44
- await this.#ids.del(hash)
45
- await this.#bucket.delete(id)
46
- await this.#updateStats(stats => {
47
- stats.count--
48
- stats.size -= size
49
- })
50
- }
37
+ await this.#wholesome(async() => {
38
+ const info = await this.#manifest.getInfo(hash)
39
+ if (info) {
40
+ await this.#manifest.deleteInfo(hash)
41
+ await this.#bucket.delete(info.id)
42
+ await this.#manifest.statsRemoveFile(info.size)
43
+ }
44
+ })
51
45
  }
52
46
 
53
47
  async write(readable: ReadableStream<Uint8Array>): Promise<Hash> {
54
48
  const id = randomId()
55
49
 
56
- await this.#wip.set(id, {created: Date.now()})
50
+ await this.#manifest.addWip(id)
57
51
  const {hash, size} = await saveAndHash(this.#bucket, id, readable)
58
- await this.#wip.del(id)
59
52
 
60
- await this.#finalizeWrite(hash, id, size)
53
+ await this.#wholesome(async() => {
54
+ if (await this.#manifest.hasHash(hash)) {
55
+ await this.#bucket.delete(id) // forget this new file (we already have it)
56
+ }
57
+ else {
58
+ await this.#manifest.saveInfo(hash, {id, size, added: Date.now()})
59
+ await this.#manifest.statsAddFile(size)
60
+ }
61
+ })
62
+
63
+ await this.#manifest.deleteWip(id)
61
64
  void this.#selfClean().catch(() => {})
62
65
  return hash
63
66
  }
64
67
 
65
68
  async* hashes() {
66
- yield* this.#ids.keys()
69
+ yield* this.#manifest.hashes()
67
70
  }
68
71
 
69
72
  async stats() {
70
- return structuredClone((await this.#stats.get()) ?? {count: 0, size: 0})
73
+ return this.#manifest.getStats()
71
74
  }
72
75
 
73
- #updateStats = queue(async(fn: (stats: Stats) => void) => {
74
- const stats = await this.stats()
75
- fn(stats)
76
- await this.#stats.set(stats)
77
- })
78
-
79
- #finalizeWrite = queue(async(hash: Hash, id: Id, size: number) => {
80
- if (await this.#ids.has(hash)) {
81
- await this.#bucket.delete(id) // forget this new file (we already have it)
82
- }
83
- else {
84
- await this.#ids.set(hash, id)
85
- await this.#updateStats(stats => {
86
- stats.count++
87
- stats.size += size
88
- })
89
- }
90
- })
91
-
92
76
  #selfClean = queue(async() => {
93
- const expiredIds = (await collect(this.#wip.entries({limit: 64})))
94
- .filter(([,wip]) => isExpired(wip))
95
- .map(([id]) => id)
77
+ const expiredIds = await this.#manifest.getExpiredIds()
96
78
  await Promise.all(expiredIds.map(id => this.#bucket.delete(id)))
97
- await this.#wip.del(...expiredIds)
79
+ await this.#manifest.deleteWip(...expiredIds)
98
80
  })
99
81
  }
100
82
 
@@ -10,10 +10,6 @@ export class MemoryBucket implements Bucket {
10
10
  return this.#map.has(id)
11
11
  }
12
12
 
13
- async size(id: Id) {
14
- return got(this.#map.get(id)).byteLength
15
- }
16
-
17
13
  async delete(id: Id) {
18
14
  this.#map.delete(id)
19
15
  }
package/s/core/types.ts CHANGED
@@ -5,18 +5,31 @@ export type Id = string
5
5
  /** file blob store. */
6
6
  export type Bucket = {
7
7
  has(id: Id): Promise<boolean>
8
- size(id: Id): Promise<number>
9
8
  delete(id: Id): Promise<void>
10
9
  read(id: Id): Promise<Blob>
11
10
  write(id: Id, readable: ReadableStream<Uint8Array>): Promise<void>
12
11
  }
13
12
 
13
+ /** metadata for a single file. */
14
+ export type Info = {
15
+
16
+ /** bucket id for this file's data. */
17
+ id: Id
18
+
19
+ /** file size in bytes. */
20
+ size: number
21
+
22
+ /** when this file was added to the datalake. */
23
+ added: number
24
+ }
25
+
26
+ /** statistics for the whole datalake. */
14
27
  export type Stats = {
15
28
 
16
29
  /** total number of bytes in the whole datalake. */
17
30
  size: number
18
31
 
19
- /** total number of known files in the datalake. */
32
+ /** total number of files in the datalake. */
20
33
  count: number
21
34
  }
22
35
 
@@ -1,9 +1,10 @@
1
1
 
2
2
  import {time} from "@e280/stz"
3
3
  import {Wip} from "../types.js"
4
+ import {consts} from "../consts.js"
4
5
 
5
6
  export function isExpired({created}: Wip) {
6
7
  const since = Date.now() - created
7
- return since > time.days(7)
8
+ return since > time.days(consts.expiry_time)
8
9
  }
9
10
 
@@ -0,0 +1,89 @@
1
+
2
+ import {Kv} from "@e280/kv"
3
+ import {collect, got} from "@e280/stz"
4
+ import {consts} from "../consts.js"
5
+ import {notFound} from "./not-found.js"
6
+ import {isExpired} from "./is-expired.js"
7
+ import {Hash, Id, Info, Stats, Wip} from "../types.js"
8
+
9
+ export class Manifest {
10
+
11
+ /** associates file hashes with bucket ids */
12
+ #info
13
+
14
+ /** temporary record of writes in-progress */
15
+ #wip
16
+
17
+ /** statistics about the whole datalake */
18
+ #stats
19
+
20
+ constructor(kv = new Kv()) {
21
+ this.#info = kv.scope<Info>("info")
22
+ this.#wip = kv.scope<Wip>("wip")
23
+ this.#stats = kv.store<Stats>("stats")
24
+ }
25
+
26
+ async* hashes() {
27
+ yield* this.#info.keys()
28
+ }
29
+
30
+ async hasHash(hash: Hash) {
31
+ return this.#info.has(hash)
32
+ }
33
+
34
+ async saveInfo(hash: Hash, info: Info) {
35
+ await this.#info.set(hash, info)
36
+ }
37
+
38
+ async getInfo(hash: Hash) {
39
+ return await this.#info.get(hash)
40
+ }
41
+
42
+ async needInfo(hash: Hash) {
43
+ return got(await this.getInfo(hash), notFound(hash))
44
+ }
45
+
46
+ async deleteInfo(hash: Hash) {
47
+ await this.#info.del(hash)
48
+ }
49
+
50
+ async addWip(id: Id) {
51
+ await this.#wip.set(id, {created: Date.now()})
52
+ }
53
+
54
+ async deleteWip(...ids: Id[]) {
55
+ await this.#wip.del(...ids)
56
+ }
57
+
58
+ async statsAddFile(size: number) {
59
+ await this.#updateStats(stats => {
60
+ stats.count += 1
61
+ stats.size += size
62
+ })
63
+ }
64
+
65
+ async statsRemoveFile(size: number) {
66
+ await this.#updateStats(stats => {
67
+ stats.count -= 1
68
+ stats.size -= size
69
+ })
70
+ }
71
+
72
+ async getExpiredIds() {
73
+ const limit = consts.self_clean_limit
74
+ return (await collect(this.#wip.entries({limit})))
75
+ .filter(([,wip]) => isExpired(wip))
76
+ .map(([id]) => id)
77
+ }
78
+
79
+ async getStats() {
80
+ return structuredClone((await this.#stats.get()) ?? {count: 0, size: 0})
81
+ }
82
+
83
+ async #updateStats(fn: (stats: Stats) => void) {
84
+ const stats = await this.getStats()
85
+ fn(stats)
86
+ await this.#stats.set(stats)
87
+ }
88
+ }
89
+
@@ -26,11 +26,6 @@ export class DiskBucket implements Bucket {
26
26
  }
27
27
  }
28
28
 
29
- async size(id: Id) {
30
- const stats = await stat(this.#path(id))
31
- return stats.size
32
- }
33
-
34
29
  async delete(id: Id) {
35
30
  try {
36
31
  await unlink(this.#path(id))
package/s/test.ts CHANGED
@@ -50,7 +50,7 @@ await science.run({
50
50
  ".write empty file": test(async() => {
51
51
  const {mammoth} = setup()
52
52
  const hash = await mammoth.write(new Blob().stream())
53
- expect(await mammoth.size(hash)).is(0)
53
+ expect((await mammoth.info(hash)).size).is(0)
54
54
  expect((await mammoth.read(hash)).size).is(0)
55
55
  }),
56
56
 
@@ -84,8 +84,9 @@ await science.run({
84
84
 
85
85
  ".size": test(async() => {
86
86
  const {mammoth} = setup()
87
- const hash = await mammoth.write(blob().stream())
88
- expect(await mammoth.size(hash)).is(4)
87
+ const b = blob()
88
+ const hash = await mammoth.write(b.stream())
89
+ expect((await mammoth.info(hash)).size).is(b.size)
89
90
  }),
90
91
 
91
92
  ".delete": test(async() => {
@@ -3,7 +3,6 @@ export declare class OpfsBucket implements Bucket {
3
3
  #private;
4
4
  constructor(directory: FileSystemDirectoryHandle);
5
5
  has(id: Id): Promise<boolean>;
6
- size(id: Id): Promise<number>;
7
6
  delete(id: Id): Promise<void>;
8
7
  read(id: Id): Promise<File>;
9
8
  write(id: Id, readable: ReadableStream<Uint8Array>): Promise<void>;
@@ -15,11 +15,6 @@ export class OpfsBucket {
15
15
  throw error;
16
16
  }
17
17
  }
18
- async size(id) {
19
- const handle = await this.#directory.getFileHandle(id);
20
- const file = await handle.getFile();
21
- return file.size;
22
- }
23
18
  async delete(id) {
24
19
  try {
25
20
  await this.#directory.removeEntry(id);
@@ -1 +1 @@
1
- {"version":3,"file":"opfs-bucket.js","sourceRoot":"","sources":["../../s/browser/opfs-bucket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAA;AAElD,MAAM,OAAO,UAAU;IACtB,UAAU,CAAA;IAEV,YAAY,SAAoC;QAC/C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAM;QACf,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;YACvC,OAAO,IAAI,CAAA;QACZ,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAA;YACnC,MAAM,KAAK,CAAA;QACZ,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAM;QAChB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;QACtD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,CAAA;QACnC,OAAO,IAAI,CAAC,IAAI,CAAA;IACjB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAM;QAClB,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QACtC,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;gBACrB,MAAM,KAAK,CAAA;QACb,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAM;QAChB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;QACtD,OAAO,MAAM,CAAC,OAAO,EAAE,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,EAAM,EAAE,QAAoC;QACvD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAA;QACtE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,CAAA;QAC9C,MAAM,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAChC,CAAC;CACD"}
1
+ {"version":3,"file":"opfs-bucket.js","sourceRoot":"","sources":["../../s/browser/opfs-bucket.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAA;AAElD,MAAM,OAAO,UAAU;IACtB,UAAU,CAAA;IAEV,YAAY,SAAoC;QAC/C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAM;QACf,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;YACvC,OAAO,IAAI,CAAA;QACZ,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAA;YACnC,MAAM,KAAK,CAAA;QACZ,CAAC;IACF,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAM;QAClB,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QACtC,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;gBACrB,MAAM,KAAK,CAAA;QACb,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAM;QAChB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC,CAAA;QACtD,OAAO,MAAM,CAAC,OAAO,EAAE,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,EAAM,EAAE,QAAoC;QACvD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAA;QACtE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,cAAc,EAAE,CAAA;QAC9C,MAAM,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAChC,CAAC;CACD"}
@@ -0,0 +1,5 @@
1
+ export declare const consts: {
2
+ max_jobs: number;
3
+ self_clean_limit: number;
4
+ expiry_time: number;
5
+ };
@@ -0,0 +1,7 @@
1
+ import { time } from "@e280/stz";
2
+ export const consts = {
3
+ max_jobs: 64,
4
+ self_clean_limit: 64,
5
+ expiry_time: time.days(7),
6
+ };
7
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../s/core/consts.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAE9B,MAAM,CAAC,MAAM,MAAM,GAAG;IACrB,QAAQ,EAAE,EAAE;IACZ,gBAAgB,EAAE,EAAE;IACpB,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;CACzB,CAAA"}
@@ -1,14 +1,14 @@
1
1
  import { Kv } from "@e280/kv";
2
- import { Hash, Bucket, Stats } from "./types.js";
2
+ import { Hash, Bucket } from "./types.js";
3
3
  /** file storage datalake, content-addressed with blake3 hashes. */
4
4
  export declare class Mammoth {
5
5
  #private;
6
6
  constructor(bucket?: Bucket, kv?: Kv<any>);
7
7
  has(hash: Hash): Promise<boolean>;
8
- size(hash: Hash): Promise<number>;
8
+ info(hash: Hash): Promise<import("./types.js").Info>;
9
9
  read(hash: Hash): Promise<Blob>;
10
10
  delete(hash: Hash): Promise<void>;
11
11
  write(readable: ReadableStream<Uint8Array>): Promise<Hash>;
12
12
  hashes(): AsyncGenerator<string, void, unknown>;
13
- stats(): Promise<Stats>;
13
+ stats(): Promise<import("./types.js").Stats>;
14
14
  }
package/x/core/mammoth.js CHANGED
@@ -1,83 +1,66 @@
1
1
  import { Kv } from "@e280/kv";
2
- import { collect, got, queue } from "@e280/stz";
2
+ import { lane, queue } from "@e280/stz";
3
+ import { consts } from "./consts.js";
4
+ import { Manifest } from "./utils/manifest.js";
3
5
  import { randomId } from "./utils/random-id.js";
4
- import { notFound } from "./utils/not-found.js";
5
6
  import { MemoryBucket } from "./memory-bucket.js";
6
- import { isExpired } from "./utils/is-expired.js";
7
7
  import { saveAndHash } from "./utils/save-and-hash.js";
8
8
  /** file storage datalake, content-addressed with blake3 hashes. */
9
9
  export class Mammoth {
10
- #ids; // associates file hashes with bucket ids
11
- #wip; // temporary record of writes in-progress
12
- #stats; // statistics about the whole datalake
13
- #bucket; // file blobstore
10
+ #bucket;
11
+ #manifest;
12
+ #wholesome = lane(consts.max_jobs);
14
13
  constructor(bucket = new MemoryBucket(), kv = new Kv()) {
15
- this.#ids = kv.scope("ids");
16
- this.#wip = kv.scope("wip");
17
- this.#stats = kv.store("stats");
18
14
  this.#bucket = bucket;
15
+ this.#manifest = new Manifest(kv);
19
16
  }
20
17
  async has(hash) {
21
- return this.#ids.has(hash);
18
+ return this.#manifest.hasHash(hash);
22
19
  }
23
- async size(hash) {
24
- const id = got(await this.#ids.get(hash), notFound(hash));
25
- return this.#bucket.size(id);
20
+ async info(hash) {
21
+ return this.#manifest.needInfo(hash);
26
22
  }
27
23
  async read(hash) {
28
- const id = got(await this.#ids.get(hash), notFound(hash));
24
+ const { id } = await this.#manifest.needInfo(hash);
29
25
  return this.#bucket.read(id);
30
26
  }
31
27
  async delete(hash) {
32
- const id = await this.#ids.get(hash);
33
- if (id) {
34
- const size = await this.#bucket.size(id);
35
- await this.#ids.del(hash);
36
- await this.#bucket.delete(id);
37
- await this.#updateStats(stats => {
38
- stats.count--;
39
- stats.size -= size;
40
- });
41
- }
28
+ await this.#wholesome(async () => {
29
+ const info = await this.#manifest.getInfo(hash);
30
+ if (info) {
31
+ await this.#manifest.deleteInfo(hash);
32
+ await this.#bucket.delete(info.id);
33
+ await this.#manifest.statsRemoveFile(info.size);
34
+ }
35
+ });
42
36
  }
43
37
  async write(readable) {
44
38
  const id = randomId();
45
- await this.#wip.set(id, { created: Date.now() });
39
+ await this.#manifest.addWip(id);
46
40
  const { hash, size } = await saveAndHash(this.#bucket, id, readable);
47
- await this.#wip.del(id);
48
- await this.#finalizeWrite(hash, id, size);
41
+ await this.#wholesome(async () => {
42
+ if (await this.#manifest.hasHash(hash)) {
43
+ await this.#bucket.delete(id); // forget this new file (we already have it)
44
+ }
45
+ else {
46
+ await this.#manifest.saveInfo(hash, { id, size, added: Date.now() });
47
+ await this.#manifest.statsAddFile(size);
48
+ }
49
+ });
50
+ await this.#manifest.deleteWip(id);
49
51
  void this.#selfClean().catch(() => { });
50
52
  return hash;
51
53
  }
52
54
  async *hashes() {
53
- yield* this.#ids.keys();
55
+ yield* this.#manifest.hashes();
54
56
  }
55
57
  async stats() {
56
- return structuredClone((await this.#stats.get()) ?? { count: 0, size: 0 });
58
+ return this.#manifest.getStats();
57
59
  }
58
- #updateStats = queue(async (fn) => {
59
- const stats = await this.stats();
60
- fn(stats);
61
- await this.#stats.set(stats);
62
- });
63
- #finalizeWrite = queue(async (hash, id, size) => {
64
- if (await this.#ids.has(hash)) {
65
- await this.#bucket.delete(id); // forget this new file (we already have it)
66
- }
67
- else {
68
- await this.#ids.set(hash, id);
69
- await this.#updateStats(stats => {
70
- stats.count++;
71
- stats.size += size;
72
- });
73
- }
74
- });
75
60
  #selfClean = queue(async () => {
76
- const expiredIds = (await collect(this.#wip.entries({ limit: 64 })))
77
- .filter(([, wip]) => isExpired(wip))
78
- .map(([id]) => id);
61
+ const expiredIds = await this.#manifest.getExpiredIds();
79
62
  await Promise.all(expiredIds.map(id => this.#bucket.delete(id)));
80
- await this.#wip.del(...expiredIds);
63
+ await this.#manifest.deleteWip(...expiredIds);
81
64
  });
82
65
  }
83
66
  //# sourceMappingURL=mammoth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mammoth.js","sourceRoot":"","sources":["../../s/core/mammoth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mammoth.js","sourceRoot":"","sources":["../../s/core/mammoth.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,6 @@ import { Bucket, Id } from "./types.js";
2
2
  export declare class MemoryBucket implements Bucket {
3
3
  #private;
4
4
  has(id: Id): Promise<boolean>;
5
- size(id: Id): Promise<number>;
6
5
  delete(id: Id): Promise<void>;
7
6
  read(id: Id): Promise<Blob>;
8
7
  write(id: Id, readable: ReadableStream<Uint8Array>): Promise<void>;
@@ -5,9 +5,6 @@ export class MemoryBucket {
5
5
  async has(id) {
6
6
  return this.#map.has(id);
7
7
  }
8
- async size(id) {
9
- return got(this.#map.get(id)).byteLength;
10
- }
11
8
  async delete(id) {
12
9
  this.#map.delete(id);
13
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"memory-bucket.js","sourceRoot":"","sources":["../../s/core/memory-bucket.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAC,MAAM,WAAW,CAAA;AAEzC,OAAO,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAA;AAE1C,MAAM,OAAO,YAAY;IACxB,IAAI,GAAG,IAAI,GAAG,EAAsB,CAAA;IAEpC,KAAK,CAAC,GAAG,CAAC,EAAM;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAM;QAChB,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAM;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAM;QAChB,OAAO,IAAI,IAAI,CACd,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAA4B,CAAC,EACnD,EAAC,IAAI,EAAE,0BAA0B,EAAC,CAClC,CAAA;IACF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,EAAM,EAAE,QAAoC;QACvD,MAAM,KAAK,GAAG,OAAO,EAAE,CAAA;QACvB,MAAM,KAAK,GAAiB,EAAE,CAAA;QAE9B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACjB,IAAI,KAAK,EAAE;gBAAE,MAAM,GAAG,EAAE,CAAA;QACzB,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACnC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC3B,CAAC;CACD"}
1
+ {"version":3,"file":"memory-bucket.js","sourceRoot":"","sources":["../../s/core/memory-bucket.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAC,MAAM,WAAW,CAAA;AAEzC,OAAO,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAA;AAE1C,MAAM,OAAO,YAAY;IACxB,IAAI,GAAG,IAAI,GAAG,EAAsB,CAAA;IAEpC,KAAK,CAAC,GAAG,CAAC,EAAM;QACf,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAM;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAM;QAChB,OAAO,IAAI,IAAI,CACd,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAA4B,CAAC,EACnD,EAAC,IAAI,EAAE,0BAA0B,EAAC,CAClC,CAAA;IACF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,EAAM,EAAE,QAAoC;QACvD,MAAM,KAAK,GAAG,OAAO,EAAE,CAAA;QACvB,MAAM,KAAK,GAAiB,EAAE,CAAA;QAE9B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YACpC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACjB,IAAI,KAAK,EAAE;gBAAE,MAAM,GAAG,EAAE,CAAA;QACzB,CAAC;QAED,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACnC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IAC3B,CAAC;CACD"}
package/x/core/types.d.ts CHANGED
@@ -3,15 +3,24 @@ export type Id = string;
3
3
  /** file blob store. */
4
4
  export type Bucket = {
5
5
  has(id: Id): Promise<boolean>;
6
- size(id: Id): Promise<number>;
7
6
  delete(id: Id): Promise<void>;
8
7
  read(id: Id): Promise<Blob>;
9
8
  write(id: Id, readable: ReadableStream<Uint8Array>): Promise<void>;
10
9
  };
10
+ /** metadata for a single file. */
11
+ export type Info = {
12
+ /** bucket id for this file's data. */
13
+ id: Id;
14
+ /** file size in bytes. */
15
+ size: number;
16
+ /** when this file was added to the datalake. */
17
+ added: number;
18
+ };
19
+ /** statistics for the whole datalake. */
11
20
  export type Stats = {
12
21
  /** total number of bytes in the whole datalake. */
13
22
  size: number;
14
- /** total number of known files in the datalake. */
23
+ /** total number of files in the datalake. */
15
24
  count: number;
16
25
  };
17
26
  export type Wip = {
@@ -1,6 +1,7 @@
1
1
  import { time } from "@e280/stz";
2
+ import { consts } from "../consts.js";
2
3
  export function isExpired({ created }) {
3
4
  const since = Date.now() - created;
4
- return since > time.days(7);
5
+ return since > time.days(consts.expiry_time);
5
6
  }
6
7
  //# sourceMappingURL=is-expired.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"is-expired.js","sourceRoot":"","sources":["../../../s/core/utils/is-expired.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAG9B,MAAM,UAAU,SAAS,CAAC,EAAC,OAAO,EAAM;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAA;IAClC,OAAO,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAC5B,CAAC"}
1
+ {"version":3,"file":"is-expired.js","sourceRoot":"","sources":["../../../s/core/utils/is-expired.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAE9B,OAAO,EAAC,MAAM,EAAC,MAAM,cAAc,CAAA;AAEnC,MAAM,UAAU,SAAS,CAAC,EAAC,OAAO,EAAM;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAA;IAClC,OAAO,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;AAC7C,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Kv } from "@e280/kv";
2
+ import { Hash, Id, Info, Stats } from "../types.js";
3
+ export declare class Manifest {
4
+ #private;
5
+ constructor(kv?: Kv<any>);
6
+ hashes(): AsyncGenerator<string, void, unknown>;
7
+ hasHash(hash: Hash): Promise<boolean>;
8
+ saveInfo(hash: Hash, info: Info): Promise<void>;
9
+ getInfo(hash: Hash): Promise<Info | undefined>;
10
+ needInfo(hash: Hash): Promise<Info>;
11
+ deleteInfo(hash: Hash): Promise<void>;
12
+ addWip(id: Id): Promise<void>;
13
+ deleteWip(...ids: Id[]): Promise<void>;
14
+ statsAddFile(size: number): Promise<void>;
15
+ statsRemoveFile(size: number): Promise<void>;
16
+ getExpiredIds(): Promise<string[]>;
17
+ getStats(): Promise<Stats>;
18
+ }
@@ -0,0 +1,69 @@
1
+ import { Kv } from "@e280/kv";
2
+ import { collect, got } from "@e280/stz";
3
+ import { consts } from "../consts.js";
4
+ import { notFound } from "./not-found.js";
5
+ import { isExpired } from "./is-expired.js";
6
+ export class Manifest {
7
+ /** associates file hashes with bucket ids */
8
+ #info;
9
+ /** temporary record of writes in-progress */
10
+ #wip;
11
+ /** statistics about the whole datalake */
12
+ #stats;
13
+ constructor(kv = new Kv()) {
14
+ this.#info = kv.scope("info");
15
+ this.#wip = kv.scope("wip");
16
+ this.#stats = kv.store("stats");
17
+ }
18
+ async *hashes() {
19
+ yield* this.#info.keys();
20
+ }
21
+ async hasHash(hash) {
22
+ return this.#info.has(hash);
23
+ }
24
+ async saveInfo(hash, info) {
25
+ await this.#info.set(hash, info);
26
+ }
27
+ async getInfo(hash) {
28
+ return await this.#info.get(hash);
29
+ }
30
+ async needInfo(hash) {
31
+ return got(await this.getInfo(hash), notFound(hash));
32
+ }
33
+ async deleteInfo(hash) {
34
+ await this.#info.del(hash);
35
+ }
36
+ async addWip(id) {
37
+ await this.#wip.set(id, { created: Date.now() });
38
+ }
39
+ async deleteWip(...ids) {
40
+ await this.#wip.del(...ids);
41
+ }
42
+ async statsAddFile(size) {
43
+ await this.#updateStats(stats => {
44
+ stats.count += 1;
45
+ stats.size += size;
46
+ });
47
+ }
48
+ async statsRemoveFile(size) {
49
+ await this.#updateStats(stats => {
50
+ stats.count -= 1;
51
+ stats.size -= size;
52
+ });
53
+ }
54
+ async getExpiredIds() {
55
+ const limit = consts.self_clean_limit;
56
+ return (await collect(this.#wip.entries({ limit })))
57
+ .filter(([, wip]) => isExpired(wip))
58
+ .map(([id]) => id);
59
+ }
60
+ async getStats() {
61
+ return structuredClone((await this.#stats.get()) ?? { count: 0, size: 0 });
62
+ }
63
+ async #updateStats(fn) {
64
+ const stats = await this.getStats();
65
+ fn(stats);
66
+ await this.#stats.set(stats);
67
+ }
68
+ }
69
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../s/core/utils/manifest.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,6 @@ export declare class DiskBucket implements Bucket {
3
3
  #private;
4
4
  constructor(directory: string);
5
5
  has(id: Id): Promise<boolean>;
6
- size(id: Id): Promise<number>;
7
6
  delete(id: Id): Promise<void>;
8
7
  read(id: Id): Promise<Blob>;
9
8
  write(id: Id, readable: ReadableStream<Uint8Array>): Promise<void>;
@@ -20,10 +20,6 @@ export class DiskBucket {
20
20
  throw error;
21
21
  }
22
22
  }
23
- async size(id) {
24
- const stats = await stat(this.#path(id));
25
- return stats.size;
26
- }
27
23
  async delete(id) {
28
24
  try {
29
25
  await unlink(this.#path(id));
@@ -1 +1 @@
1
- {"version":3,"file":"disk-bucket.js","sourceRoot":"","sources":["../../s/node/disk-bucket.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AACpC,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAC,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAC,iBAAiB,EAAE,UAAU,EAAC,MAAM,SAAS,CAAA;AAGrD,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAA;AAElD,MAAM,OAAO,UAAU;IACtB,UAAU,CAAA;IAEV,YAAY,SAAiB;QAC5B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAM;QACf,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;YAC1B,OAAO,IAAI,CAAA;QACZ,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAA;YACnC,MAAM,KAAK,CAAA;QACZ,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAM;QAChB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QACxC,OAAO,KAAK,CAAC,IAAI,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAM;QAClB,IAAI,CAAC;YACJ,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAC7B,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;gBACrB,MAAM,KAAK,CAAA;QACb,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAM;QAChB,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,EAAM,EAAE,QAAoC;QACvD,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;QAC/C,MAAM,QAAQ,CACb,QAAQ,CAAC,OAAO,CAAC,QAAe,CAAC,EACjC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CACjC,CAAA;IACF,CAAC;IAED,KAAK,CAAC,EAAM;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IACjC,CAAC;CACD"}
1
+ {"version":3,"file":"disk-bucket.js","sourceRoot":"","sources":["../../s/node/disk-bucket.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AACpC,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAC,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAC,iBAAiB,EAAE,UAAU,EAAC,MAAM,SAAS,CAAA;AAGrD,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAA;AAElD,MAAM,OAAO,UAAU;IACtB,UAAU,CAAA;IAEV,YAAY,SAAiB;QAC5B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAM;QACf,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;YAC1B,OAAO,IAAI,CAAA;QACZ,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,UAAU,CAAC,KAAK,CAAC;gBAAE,OAAO,KAAK,CAAA;YACnC,MAAM,KAAK,CAAA;QACZ,CAAC;IACF,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAM;QAClB,IAAI,CAAC;YACJ,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;QAC7B,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACd,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;gBACrB,MAAM,KAAK,CAAA;QACb,CAAC;IACF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAM;QAChB,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,EAAM,EAAE,QAAoC;QACvD,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAA;QAC/C,MAAM,QAAQ,CACb,QAAQ,CAAC,OAAO,CAAC,QAAe,CAAC,EACjC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CACjC,CAAA;IACF,CAAC;IAED,KAAK,CAAC,EAAM;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IACjC,CAAC;CACD"}
package/x/test.js CHANGED
@@ -42,7 +42,7 @@ await science.run({
42
42
  ".write empty file": test(async () => {
43
43
  const { mammoth } = setup();
44
44
  const hash = await mammoth.write(new Blob().stream());
45
- expect(await mammoth.size(hash)).is(0);
45
+ expect((await mammoth.info(hash)).size).is(0);
46
46
  expect((await mammoth.read(hash)).size).is(0);
47
47
  }),
48
48
  ".write distinct files": test(async () => {
@@ -72,8 +72,9 @@ await science.run({
72
72
  }),
73
73
  ".size": test(async () => {
74
74
  const { mammoth } = setup();
75
- const hash = await mammoth.write(blob().stream());
76
- expect(await mammoth.size(hash)).is(4);
75
+ const b = blob();
76
+ const hash = await mammoth.write(b.stream());
77
+ expect((await mammoth.info(hash)).size).is(b.size);
77
78
  }),
78
79
  ".delete": test(async () => {
79
80
  const { mammoth } = setup();
package/x/test.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"test.js","sourceRoot":"","sources":["../s/test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../s/test.ts"],"names":[],"mappings":"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"}