@e280/mammoth 0.1.0-2 → 0.1.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.
Files changed (44) hide show
  1. package/README.md +86 -4
  2. package/package.json +3 -2
  3. package/s/browser/example.ts +9 -10
  4. package/s/browser/index.ts +1 -1
  5. package/s/browser/{iceberg-opfs.ts → opfs-bucket.ts} +2 -2
  6. package/s/core/index.ts +1 -1
  7. package/s/core/mammoth.ts +95 -29
  8. package/s/core/{iceberg-memory.ts → memory-bucket.ts} +2 -2
  9. package/s/core/types.ts +3 -8
  10. package/s/node/disk-bucket.ts +60 -0
  11. package/s/node/index.ts +4 -0
  12. package/s/node/utils/is-not-found.ts +9 -0
  13. package/s/test.ts +34 -8
  14. package/x/browser/example.js +9 -10
  15. package/x/browser/example.js.map +1 -1
  16. package/x/browser/index.d.ts +1 -1
  17. package/x/browser/index.js +1 -1
  18. package/x/browser/index.js.map +1 -1
  19. package/x/browser/{iceberg-opfs.d.ts → opfs-bucket.d.ts} +2 -2
  20. package/x/browser/{iceberg-opfs.js → opfs-bucket.js} +2 -2
  21. package/x/browser/opfs-bucket.js.map +1 -0
  22. package/x/core/index.d.ts +1 -1
  23. package/x/core/index.js +1 -1
  24. package/x/core/index.js.map +1 -1
  25. package/x/core/mammoth.d.ts +12 -4
  26. package/x/core/mammoth.js +77 -27
  27. package/x/core/mammoth.js.map +1 -1
  28. package/x/core/{iceberg-memory.d.ts → memory-bucket.d.ts} +2 -2
  29. package/x/core/{iceberg-memory.js → memory-bucket.js} +2 -2
  30. package/x/core/memory-bucket.js.map +1 -0
  31. package/x/core/types.d.ts +3 -8
  32. package/x/node/disk-bucket.d.ts +10 -0
  33. package/x/node/disk-bucket.js +47 -0
  34. package/x/node/disk-bucket.js.map +1 -0
  35. package/x/node/index.d.ts +2 -0
  36. package/x/node/index.js +3 -0
  37. package/x/node/index.js.map +1 -0
  38. package/x/node/utils/is-not-found.d.ts +1 -0
  39. package/x/node/utils/is-not-found.js +6 -0
  40. package/x/node/utils/is-not-found.js.map +1 -0
  41. package/x/test.js +32 -8
  42. package/x/test.js.map +1 -1
  43. package/x/browser/iceberg-opfs.js.map +0 -1
  44. package/x/core/iceberg-memory.js.map +0 -1
package/README.md CHANGED
@@ -1,13 +1,95 @@
1
1
 
2
+ ![](https://i.imgur.com/qqiMrZ5.png)
3
+
2
4
  # 🦣 @e280/mammoth
5
+ ## big files. small api.
6
+
7
+ ```bash
8
+ npm install @e280/mammoth
9
+ ```
10
+
11
+ ```ts
12
+ import {Mammoth} from "@e280/mammoth"
13
+
14
+ const mammoth = new Mammoth()
15
+ ```
16
+
17
+ ### 🦣 mammoth stores files.
18
+ - **write a file,** and you get back its blake3 hash.
19
+ ```ts
20
+ const hash = await mammoth.write(blob.stream())
21
+ ```
22
+ - **read a file,** identified by its hash.
23
+ ```ts
24
+ const blob = await mammoth.read(hash)
25
+ ```
26
+ - **delete a file.**
27
+ ```ts
28
+ await mammoth.delete(hash)
29
+ ```
30
+
31
+ ### 🦣 mammoth is bucket-agnostic.
32
+ - **memory bucket,** for testing.
33
+ ```ts
34
+ import {Mammoth, MemoryBucket} from "@e280/mammoth"
35
+ import {Kv} from "@e280/kv"
36
+
37
+ const mammoth = new Mammoth(
38
+ new Kv(),
39
+ new MemoryBucket(),
40
+ )
41
+ ```
42
+ defaults shown, so, this is equivalent:
43
+ ```ts
44
+ const mammoth = new Mammoth()
45
+ ```
46
+ - **disk bucket,** for nodejs servers. *(note the import paths)*
47
+ ```ts
48
+ import {Mammoth} from "@e280/mammoth"
49
+ import {DiskBucket} from "@e280/mammoth/node"
50
+ import {Kv} from "@e280/kv"
51
+ import {LevelDriver} from "@e280/kv/level"
52
+
53
+ const mammoth = new Mammoth(
54
+ new Kv(new LevelDriver("./data/kv")),
55
+ new DiskBucket("./data/bucket"),
56
+ )
57
+ ```
58
+ - **opfs bucket,** for local storage in the browser. *(note the import paths)*
59
+ ```ts
60
+ import {Mammoth} from "@e280/mammoth"
61
+ import {OpfsBucket} from "@e280/mammoth/browser"
62
+ import {Kv, StorageDriver} from "@e280/kv"
63
+
64
+ const mammoth = new Mammoth(
65
+ new Kv(new StorageDriver(localStorage)),
66
+ new OpfsBucket(await navigator.storage.getDirectory()),
67
+ )
68
+ ```
3
69
 
4
- big files. small api.
70
+ ### 🦣 mammoth has a few more methods for you.
71
+ - **check if a file exists,** get back a boolean.
72
+ ```ts
73
+ const exists = await mammoth.has(hash)
74
+ ```
75
+ - **get file size,** in bytes.
76
+ ```ts
77
+ const size = await mammoth.size(hash)
78
+ ```
79
+ - **get stats,** for the whole datalake.
80
+ ```ts
81
+ await mammoth.stats()
82
+ // {size: 1234567}
83
+ ```
84
+ - **loop over all hashes,** for all stored files.
85
+ ```ts
86
+ for await (const hash of mammoth.hashes())
87
+ console.log(hash)
88
+ ```
5
89
 
6
90
 
7
91
 
8
92
  <br/><br/>
9
93
 
10
- ## 💖 mammoth is by e280
11
- reward us with github stars
12
- build with us at https://e280.org/ but only if you're cool
94
+ > *by [e280](https://e280.org/)*
13
95
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e280/mammoth",
3
- "version": "0.1.0-2",
3
+ "version": "0.1.0-4",
4
4
  "description": "big file storage",
5
5
  "license": "MIT",
6
6
  "author": "Chase Moskal <chasemoskal@gmail.com>",
@@ -9,7 +9,8 @@
9
9
  "sideEffects": false,
10
10
  "exports": {
11
11
  ".": "./x/core/index.js",
12
- "./browser": "./x/browser/index.js"
12
+ "./browser": "./x/browser/index.js",
13
+ "./node": "./x/node/index.js"
13
14
  },
14
15
  "files": [
15
16
  "x",
@@ -1,26 +1,25 @@
1
1
 
2
2
  import {Kv, StorageDriver} from "@e280/kv"
3
3
  import {Mammoth} from "../core/mammoth.js"
4
- import {IcebergOpfs} from "./iceberg-opfs.js"
4
+ import {OpfsBucket} from "./opfs-bucket.js"
5
5
 
6
6
  export async function example() {
7
7
 
8
- // setup the localstorage kv index
8
+ // setup the localstorage kv
9
9
  const driver = new StorageDriver(window.localStorage)
10
- const kv = new Kv(driver)
11
- const index = kv.scope("glacier_index")
10
+ const kv = new Kv(driver).scope("mammoth")
12
11
 
13
- // setup the opfs iceberg
12
+ // setup the opfs file bucket
14
13
  const root = await navigator.storage.getDirectory()
15
- const directory = await root.getDirectoryHandle("glacier", {create: true})
16
- const iceberg = new IcebergOpfs(directory)
14
+ const directory = await root.getDirectoryHandle("mammoth", {create: true})
15
+ const bucket = new OpfsBucket(directory)
17
16
 
18
17
  // setup the mammoth
19
- const mammoth = new Mammoth(index, iceberg)
20
- const bigFile = new Blob([new Uint8Array([0xDE, 0xAD, 0xBE, 0xEF])])
18
+ const mammoth = new Mammoth(kv, bucket)
19
+ const myFile = new Blob([new Uint8Array([0xDE, 0xAD, 0xBE, 0xEF])])
21
20
 
22
21
  // write a file as an example
23
- const hash = await mammoth.write(bigFile.stream())
22
+ const hash = await mammoth.write(myFile.stream())
24
23
  console.log(`mammoth stored file by hash "${hash}"`)
25
24
  }
26
25
 
@@ -1,4 +1,4 @@
1
1
 
2
2
  export * from "../core/index.js"
3
- export * from "./iceberg-opfs.js"
3
+ export * from "./opfs-bucket.js"
4
4
 
@@ -1,8 +1,8 @@
1
1
 
2
- import {Iceberg, Id} from "../core/types.js"
2
+ import {Bucket, Id} from "../core/types.js"
3
3
  import {isNotFound} from "./utils/is-not-found.js"
4
4
 
5
- export class IcebergOpfs implements Iceberg {
5
+ export class OpfsBucket implements Bucket {
6
6
  #directory
7
7
 
8
8
  constructor(directory: FileSystemDirectoryHandle) {
package/s/core/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  export * from "./hash-stream.js"
3
- export * from "./iceberg-memory.js"
3
+ export * from "./memory-bucket.js"
4
4
  export * from "./mammoth.js"
5
5
  export * from "./types.js"
6
6
 
package/s/core/mammoth.ts CHANGED
@@ -1,72 +1,138 @@
1
1
 
2
2
  import {Kv} from "@e280/kv"
3
- import {got, hex} from "@e280/stz"
3
+ import {got, hex, queue, time} from "@e280/stz"
4
4
  import {blake3} from "@noble/hashes/blake3.js"
5
5
 
6
+ import {Hash, Bucket, Id} from "./types.js"
6
7
  import {randomId} from "./utils/random-id.js"
7
- import {Glacier, Hash, Iceberg, Id} from "./types.js"
8
+ import {MemoryBucket} from "./memory-bucket.js"
8
9
 
9
- export class Mammoth implements Glacier {
10
- #index
11
- #iceberg
10
+ /** file storage datalake, content-addressed with blake3 hashes. */
11
+ export class Mammoth {
12
+ #ids
13
+ #wip
14
+ #stats
15
+ #bucket
12
16
 
13
- constructor(index: Kv<string>, iceberg: Iceberg) {
14
- this.#index = index
15
- this.#iceberg = iceberg
17
+ constructor(
18
+
19
+ /** key-value metadata manifest. */
20
+ kv = new Kv(),
21
+
22
+ /** dumb raw file blob storage. */
23
+ bucket: Bucket = new MemoryBucket(),
24
+
25
+ ) {
26
+ this.#ids = kv.scope<string>("ids")
27
+ this.#wip = kv.scope<{created: number}>("wip")
28
+ this.#stats = kv.store<{size: number}>("stats")
29
+ this.#bucket = bucket
16
30
  }
17
31
 
18
32
  async has(hash: Hash) {
19
- return this.#index.has(hash)
33
+ return this.#ids.has(hash)
20
34
  }
21
35
 
22
36
  async size(hash: Hash) {
23
- const id = await this.#needFileId(hash)
24
- return this.#iceberg.size(id)
37
+ const id = await this.#needId(hash)
38
+ return this.#bucket.size(id)
25
39
  }
26
40
 
27
41
  async read(hash: Hash) {
28
- const id = await this.#needFileId(hash)
29
- return this.#iceberg.read(id)
42
+ const id = await this.#needId(hash)
43
+ return this.#bucket.read(id)
30
44
  }
31
45
 
32
46
  async delete(hash: Hash) {
33
- const id = await this.#getFileId(hash)
47
+ const id = await this.#getId(hash)
34
48
  if (id) {
35
- await this.#index.del(hash)
36
- await this.#iceberg.delete(id)
49
+ const size = await this.#bucket.size(id)
50
+ await this.#ids.del(hash)
51
+ await this.#bucket.delete(id)
52
+ await this.#addSize(-size)
37
53
  }
38
54
  }
39
55
 
40
56
  async write(readable: ReadableStream<Uint8Array>): Promise<Hash> {
41
57
  const id = randomId()
58
+ await this.#wip.set(id, {created: Date.now()})
59
+
60
+ const {hash, size} = await this.#hashAndSave(id, readable)
61
+
62
+ await this.#wip.del(id)
63
+ await this.#finalizeWrite(hash, id, size)
64
+
65
+ void this.#selfClean().catch(() => {})
66
+
67
+ return hash
68
+ }
69
+
70
+ async* hashes() {
71
+ yield* this.#ids.keys()
72
+ }
73
+
74
+ async stats() {
75
+ return (await this.#stats.get()) ?? {size: 0}
76
+ }
77
+
78
+ async #getId(hash: Hash): Promise<Id | undefined> {
79
+ return this.#ids.get<string>(hash)
80
+ }
81
+
82
+ async #needId(hash: Hash): Promise<Id> {
83
+ return got(await this.#getId(hash), `file not found by hash "${hash}"`)
84
+ }
85
+
86
+ async #hashAndSave(id: Id, readable: ReadableStream<Uint8Array>) {
87
+ let size = 0
42
88
  const pipe = new TransformStream()
43
- const done = this.#iceberg.write(id, pipe.readable)
89
+ const done = this.#bucket.write(id, pipe.readable)
44
90
  const writer = pipe.writable.getWriter()
45
91
  const hasher = blake3.create()
46
92
 
47
93
  for await (const chunk of readable) {
48
94
  await writer.write(chunk as Uint8Array<ArrayBuffer>)
49
95
  hasher.update(chunk)
96
+ size += chunk.byteLength
50
97
  }
51
98
 
52
99
  await writer.close()
53
100
  await done
101
+
54
102
  const hash = hex.fromBytes(hasher.digest())
55
- await this.delete(hash)
56
- await this.#index.set(hash, id)
57
- return hash
103
+ return {hash, size}
58
104
  }
59
105
 
60
- async #getFileId(hash: Hash): Promise<Id | undefined> {
61
- return this.#index.get<string>(hash)
62
- }
106
+ #finalizeWrite = queue(async(hash: Hash, id: Id, size: number) => {
107
+ const existingId = await this.#getId(hash)
63
108
 
64
- async #needFileId(hash: Hash): Promise<Id> {
65
- return got(await this.#getFileId(hash), `file not found by hash "${hash}"`)
66
- }
109
+ if (existingId) {
110
+ await this.#bucket.delete(id)
111
+ }
112
+ else {
113
+ await this.#ids.set(hash, id)
114
+ await this.#addSize(size)
115
+ }
116
+ })
67
117
 
68
- async* keys() {
69
- yield* this.#index.keys()
70
- }
118
+ #addSize = queue(async(sizeChange: number) => {
119
+ const oldStats = await this.stats()
120
+ await this.#stats.set({...oldStats, size: oldStats.size + sizeChange})
121
+ })
122
+
123
+ #selfClean = queue(async() => {
124
+ const now = Date.now()
125
+ const expiredIds: Id[] = []
126
+
127
+ for await (const [id, {created}] of this.#wip.entries({limit: 64})) {
128
+ const since = now - created
129
+ const isExpired = since > time.days(7)
130
+ if (isExpired)
131
+ expiredIds.push(id)
132
+ }
133
+
134
+ await Promise.all(expiredIds.map(id => this.#bucket.delete(id)))
135
+ await this.#wip.del(...expiredIds)
136
+ })
71
137
  }
72
138
 
@@ -1,9 +1,9 @@
1
1
 
2
2
  import {bytes, got, nap} from "@e280/stz"
3
- import {Iceberg, Id} from "./types.js"
3
+ import {Bucket, Id} from "./types.js"
4
4
  import {relaxer} from "./utils/relaxer.js"
5
5
 
6
- export class IcebergMemory implements Iceberg {
6
+ export class MemoryBucket implements Bucket {
7
7
  #map = new Map<string, Uint8Array>()
8
8
 
9
9
  async has(id: Id) {
package/s/core/types.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  export type Hash = string
3
3
  export type Id = string
4
4
 
5
- export type Iceberg = {
5
+ export type Bucket = {
6
6
  has(id: Id): Promise<boolean>
7
7
  size(id: Id): Promise<number>
8
8
  delete(id: Id): Promise<void>
@@ -10,12 +10,7 @@ export type Iceberg = {
10
10
  write(id: Id, readable: ReadableStream<Uint8Array>): Promise<void>
11
11
  }
12
12
 
13
- export type Glacier = {
14
- has(hash: Hash): Promise<boolean>
15
- size(hash: Hash): Promise<number>
16
- read(hash: Hash): Promise<Blob>
17
- delete(hash: Hash): Promise<void>
18
- write(readable: ReadableStream<Uint8Array>): Promise<Hash>
19
- keys(): AsyncIterable<Hash>
13
+ export type Stats = {
14
+ size: number
20
15
  }
21
16
 
@@ -0,0 +1,60 @@
1
+
2
+ import {join} from "node:path"
3
+ import {Readable} from "node:stream"
4
+ import {pipeline} from "node:stream/promises"
5
+ import {mkdir, stat, unlink} from "node:fs/promises"
6
+ import {createWriteStream, openAsBlob} from "node:fs"
7
+
8
+ import {Bucket, Id} from "../core/types.js"
9
+ import {isNotFound} from "./utils/is-not-found.js"
10
+
11
+ export class DiskBucket implements Bucket {
12
+ #directory
13
+
14
+ constructor(directory: string) {
15
+ this.#directory = directory
16
+ }
17
+
18
+ async has(id: Id) {
19
+ try {
20
+ await stat(this.#path(id))
21
+ return true
22
+ }
23
+ catch (error) {
24
+ if (isNotFound(error)) return false
25
+ throw error
26
+ }
27
+ }
28
+
29
+ async size(id: Id) {
30
+ const stats = await stat(this.#path(id))
31
+ return stats.size
32
+ }
33
+
34
+ async delete(id: Id) {
35
+ try {
36
+ await unlink(this.#path(id))
37
+ }
38
+ catch (error) {
39
+ if (!isNotFound(error))
40
+ throw error
41
+ }
42
+ }
43
+
44
+ async read(id: Id) {
45
+ return openAsBlob(this.#path(id))
46
+ }
47
+
48
+ async write(id: Id, readable: ReadableStream<Uint8Array>) {
49
+ await mkdir(this.#directory, {recursive: true})
50
+ await pipeline(
51
+ Readable.fromWeb(readable as any),
52
+ createWriteStream(this.#path(id)),
53
+ )
54
+ }
55
+
56
+ #path(id: Id) {
57
+ return join(this.#directory, id)
58
+ }
59
+ }
60
+
@@ -0,0 +1,4 @@
1
+
2
+ export * from "../core/index.js"
3
+ export * from "./disk-bucket.js"
4
+
@@ -0,0 +1,9 @@
1
+
2
+ export function isNotFound(error: unknown): error is NodeJS.ErrnoException {
3
+ return (
4
+ error instanceof Error
5
+ && "code" in error
6
+ && error.code === "ENOENT"
7
+ )
8
+ }
9
+
package/s/test.ts CHANGED
@@ -1,23 +1,36 @@
1
1
 
2
2
  import {Kv} from "@e280/kv"
3
+ import {rm} from "fs/promises"
3
4
  import {bytes, collect} from "@e280/stz"
4
5
  import {science, test, expect} from "@e280/science"
5
6
 
6
7
  import {Mammoth} from "./core/mammoth.js"
8
+ import {DiskBucket} from "./node/disk-bucket.js"
7
9
  import {randomId} from "./core/utils/random-id.js"
8
- import {IcebergMemory} from "./core/iceberg-memory.js"
10
+ import {MemoryBucket} from "./core/memory-bucket.js"
9
11
 
10
12
  const blob = () => new Blob([new Uint8Array([0xDE, 0xAD, 0xBE, 0xEF])])
11
13
  const quickstream = (b: number[]) => new Blob([new Uint8Array(b)]).stream()
12
14
 
13
15
  function setup() {
14
- const index = new Kv<string>()
15
- const iceberg = new IcebergMemory()
16
- const mammoth = new Mammoth(index, iceberg)
16
+ const manifest = new Kv()
17
+ const bucket = new MemoryBucket()
18
+ const mammoth = new Mammoth(manifest, bucket)
17
19
  return {mammoth}
18
20
  }
19
21
 
20
22
  await science.run({
23
+ "mammoth node": test(async() => {
24
+ const dataDir = "data"
25
+ await rm(dataDir, {recursive: true, force: true})
26
+ const manifest = new Kv()
27
+ const bucket = new DiskBucket(dataDir)
28
+ const mammoth = new Mammoth(manifest, bucket)
29
+ const hash = await mammoth.write(blob().stream())
30
+ const second = await mammoth.read(hash)
31
+ expect(bytes.eq(await second.bytes(), await blob().bytes()))
32
+ }),
33
+
21
34
  "mammoth": {
22
35
  ".write and .read": test(async() => {
23
36
  const {mammoth} = setup()
@@ -30,7 +43,7 @@ await science.run({
30
43
  const {mammoth} = setup()
31
44
  const hashA = await mammoth.write(blob().stream())
32
45
  const hashB = await mammoth.write(blob().stream())
33
- const keys = await collect(mammoth.keys())
46
+ const keys = await collect(mammoth.hashes())
34
47
  expect(hashA).is(hashB)
35
48
  expect(keys.length).is(1)
36
49
  expect(keys[0]).is(hashA)
@@ -48,7 +61,20 @@ await science.run({
48
61
  const hashA = await mammoth.write(quickstream([0xC0, 0xFF, 0xEE]))
49
62
  const hashB = await mammoth.write(quickstream([0xB0, 0x0B, 0x1E, 0x5]))
50
63
  expect(hashA).not.is(hashB)
51
- expect((await collect(mammoth.keys())).length).is(2)
64
+ expect((await collect(mammoth.hashes())).length).is(2)
65
+ }),
66
+
67
+ ".stats": test(async() => {
68
+ const {mammoth} = setup()
69
+ expect(await mammoth.stats()).deep({size: 0})
70
+ const hashA = await mammoth.write(quickstream([0xC0, 0xFF, 0xEE]))
71
+ expect(await mammoth.stats()).deep({size: 3})
72
+ const hashB = await mammoth.write(quickstream([0xB0, 0x0B, 0x1E, 0x5]))
73
+ expect(await mammoth.stats()).deep({size: 7})
74
+ await mammoth.delete(hashA)
75
+ expect(await mammoth.stats()).deep({size: 4})
76
+ await mammoth.delete(hashB)
77
+ expect(await mammoth.stats()).deep({size: 0})
52
78
  }),
53
79
 
54
80
  ".has": test(async() => {
@@ -69,7 +95,7 @@ await science.run({
69
95
  const hash = await mammoth.write(blob().stream())
70
96
  await mammoth.delete(hash)
71
97
  expect(await mammoth.has(hash)).is(false)
72
- expect(await collect(mammoth.keys())).deep([])
98
+ expect(await collect(mammoth.hashes())).deep([])
73
99
  }),
74
100
 
75
101
  ".delete idempotent": test(async() => {
@@ -80,7 +106,7 @@ await science.run({
80
106
  ".keys": test(async() => {
81
107
  const {mammoth} = setup()
82
108
  const hash = await mammoth.write(blob().stream())
83
- const keys = await collect(mammoth.keys())
109
+ const keys = await collect(mammoth.hashes())
84
110
  expect(keys.length).is(1)
85
111
  expect(keys[0]).is(hash)
86
112
  }),
@@ -1,20 +1,19 @@
1
1
  import { Kv, StorageDriver } from "@e280/kv";
2
2
  import { Mammoth } from "../core/mammoth.js";
3
- import { IcebergOpfs } from "./iceberg-opfs.js";
3
+ import { OpfsBucket } from "./opfs-bucket.js";
4
4
  export async function example() {
5
- // setup the localstorage kv index
5
+ // setup the localstorage kv
6
6
  const driver = new StorageDriver(window.localStorage);
7
- const kv = new Kv(driver);
8
- const index = kv.scope("glacier_index");
9
- // setup the opfs iceberg
7
+ const kv = new Kv(driver).scope("mammoth");
8
+ // setup the opfs file bucket
10
9
  const root = await navigator.storage.getDirectory();
11
- const directory = await root.getDirectoryHandle("glacier", { create: true });
12
- const iceberg = new IcebergOpfs(directory);
10
+ const directory = await root.getDirectoryHandle("mammoth", { create: true });
11
+ const bucket = new OpfsBucket(directory);
13
12
  // setup the mammoth
14
- const mammoth = new Mammoth(index, iceberg);
15
- const bigFile = new Blob([new Uint8Array([0xDE, 0xAD, 0xBE, 0xEF])]);
13
+ const mammoth = new Mammoth(kv, bucket);
14
+ const myFile = new Blob([new Uint8Array([0xDE, 0xAD, 0xBE, 0xEF])]);
16
15
  // write a file as an example
17
- const hash = await mammoth.write(bigFile.stream());
16
+ const hash = await mammoth.write(myFile.stream());
18
17
  console.log(`mammoth stored file by hash "${hash}"`);
19
18
  }
20
19
  //# sourceMappingURL=example.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"example.js","sourceRoot":"","sources":["../../s/browser/example.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,EAAE,EAAE,aAAa,EAAC,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAA;AAE7C,MAAM,CAAC,KAAK,UAAU,OAAO;IAE5B,kCAAkC;IAClC,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACrD,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAA;IACzB,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAA;IAEvC,yBAAyB;IACzB,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,CAAA;IACnD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAA;IAC1E,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,CAAA;IAE1C,oBAAoB;IACpB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAC3C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAEpE,6BAA6B;IAC7B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAClD,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,GAAG,CAAC,CAAA;AACrD,CAAC"}
1
+ {"version":3,"file":"example.js","sourceRoot":"","sources":["../../s/browser/example.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,EAAE,EAAE,aAAa,EAAC,MAAM,UAAU,CAAA;AAC1C,OAAO,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAE3C,MAAM,CAAC,KAAK,UAAU,OAAO;IAE5B,4BAA4B;IAC5B,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IACrD,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IAE1C,6BAA6B;IAC7B,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,CAAA;IACnD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAC,MAAM,EAAE,IAAI,EAAC,CAAC,CAAA;IAC1E,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAA;IAExC,oBAAoB;IACpB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACvC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IAEnE,6BAA6B;IAC7B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;IACjD,OAAO,CAAC,GAAG,CAAC,gCAAgC,IAAI,GAAG,CAAC,CAAA;AACrD,CAAC"}
@@ -1,2 +1,2 @@
1
1
  export * from "../core/index.js";
2
- export * from "./iceberg-opfs.js";
2
+ export * from "./opfs-bucket.js";
@@ -1,3 +1,3 @@
1
1
  export * from "../core/index.js";
2
- export * from "./iceberg-opfs.js";
2
+ export * from "./opfs-bucket.js";
3
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../s/browser/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../s/browser/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA"}
@@ -1,5 +1,5 @@
1
- import { Iceberg, Id } from "../core/types.js";
2
- export declare class IcebergOpfs implements Iceberg {
1
+ import { Bucket, Id } from "../core/types.js";
2
+ export declare class OpfsBucket implements Bucket {
3
3
  #private;
4
4
  constructor(directory: FileSystemDirectoryHandle);
5
5
  has(id: Id): Promise<boolean>;
@@ -1,5 +1,5 @@
1
1
  import { isNotFound } from "./utils/is-not-found.js";
2
- export class IcebergOpfs {
2
+ export class OpfsBucket {
3
3
  #directory;
4
4
  constructor(directory) {
5
5
  this.#directory = directory;
@@ -39,4 +39,4 @@ export class IcebergOpfs {
39
39
  await readable.pipeTo(writable);
40
40
  }
41
41
  }
42
- //# sourceMappingURL=iceberg-opfs.js.map
42
+ //# sourceMappingURL=opfs-bucket.js.map
@@ -0,0 +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"}
package/x/core/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from "./hash-stream.js";
2
- export * from "./iceberg-memory.js";
2
+ export * from "./memory-bucket.js";
3
3
  export * from "./mammoth.js";
4
4
  export * from "./types.js";
package/x/core/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from "./hash-stream.js";
2
- export * from "./iceberg-memory.js";
2
+ export * from "./memory-bucket.js";
3
3
  export * from "./mammoth.js";
4
4
  export * from "./types.js";
5
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../s/core/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../s/core/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA"}
@@ -1,12 +1,20 @@
1
1
  import { Kv } from "@e280/kv";
2
- import { Glacier, Hash, Iceberg } from "./types.js";
3
- export declare class Mammoth implements Glacier {
2
+ import { Hash, Bucket } from "./types.js";
3
+ /** file storage datalake, content-addressed with blake3 hashes. */
4
+ export declare class Mammoth {
4
5
  #private;
5
- constructor(index: Kv<string>, iceberg: Iceberg);
6
+ constructor(
7
+ /** key-value metadata manifest. */
8
+ kv?: Kv<any>,
9
+ /** dumb raw file blob storage. */
10
+ bucket?: Bucket);
6
11
  has(hash: Hash): Promise<boolean>;
7
12
  size(hash: Hash): Promise<number>;
8
13
  read(hash: Hash): Promise<Blob>;
9
14
  delete(hash: Hash): Promise<void>;
10
15
  write(readable: ReadableStream<Uint8Array>): Promise<Hash>;
11
- keys(): AsyncGenerator<string, void, unknown>;
16
+ hashes(): AsyncGenerator<string, void, unknown>;
17
+ stats(): Promise<{
18
+ size: number;
19
+ }>;
12
20
  }
package/x/core/mammoth.js CHANGED
@@ -1,56 +1,106 @@
1
- import { got, hex } from "@e280/stz";
1
+ import { Kv } from "@e280/kv";
2
+ import { got, hex, queue, time } from "@e280/stz";
2
3
  import { blake3 } from "@noble/hashes/blake3.js";
3
4
  import { randomId } from "./utils/random-id.js";
5
+ import { MemoryBucket } from "./memory-bucket.js";
6
+ /** file storage datalake, content-addressed with blake3 hashes. */
4
7
  export class Mammoth {
5
- #index;
6
- #iceberg;
7
- constructor(index, iceberg) {
8
- this.#index = index;
9
- this.#iceberg = iceberg;
8
+ #ids;
9
+ #wip;
10
+ #stats;
11
+ #bucket;
12
+ constructor(
13
+ /** key-value metadata manifest. */
14
+ kv = new Kv(),
15
+ /** dumb raw file blob storage. */
16
+ bucket = new MemoryBucket()) {
17
+ this.#ids = kv.scope("ids");
18
+ this.#wip = kv.scope("wip");
19
+ this.#stats = kv.store("stats");
20
+ this.#bucket = bucket;
10
21
  }
11
22
  async has(hash) {
12
- return this.#index.has(hash);
23
+ return this.#ids.has(hash);
13
24
  }
14
25
  async size(hash) {
15
- const id = await this.#needFileId(hash);
16
- return this.#iceberg.size(id);
26
+ const id = await this.#needId(hash);
27
+ return this.#bucket.size(id);
17
28
  }
18
29
  async read(hash) {
19
- const id = await this.#needFileId(hash);
20
- return this.#iceberg.read(id);
30
+ const id = await this.#needId(hash);
31
+ return this.#bucket.read(id);
21
32
  }
22
33
  async delete(hash) {
23
- const id = await this.#getFileId(hash);
34
+ const id = await this.#getId(hash);
24
35
  if (id) {
25
- await this.#index.del(hash);
26
- await this.#iceberg.delete(id);
36
+ const size = await this.#bucket.size(id);
37
+ await this.#ids.del(hash);
38
+ await this.#bucket.delete(id);
39
+ await this.#addSize(-size);
27
40
  }
28
41
  }
29
42
  async write(readable) {
30
43
  const id = randomId();
44
+ await this.#wip.set(id, { created: Date.now() });
45
+ const { hash, size } = await this.#hashAndSave(id, readable);
46
+ await this.#wip.del(id);
47
+ await this.#finalizeWrite(hash, id, size);
48
+ void this.#selfClean().catch(() => { });
49
+ return hash;
50
+ }
51
+ async *hashes() {
52
+ yield* this.#ids.keys();
53
+ }
54
+ async stats() {
55
+ return (await this.#stats.get()) ?? { size: 0 };
56
+ }
57
+ async #getId(hash) {
58
+ return this.#ids.get(hash);
59
+ }
60
+ async #needId(hash) {
61
+ return got(await this.#getId(hash), `file not found by hash "${hash}"`);
62
+ }
63
+ async #hashAndSave(id, readable) {
64
+ let size = 0;
31
65
  const pipe = new TransformStream();
32
- const done = this.#iceberg.write(id, pipe.readable);
66
+ const done = this.#bucket.write(id, pipe.readable);
33
67
  const writer = pipe.writable.getWriter();
34
68
  const hasher = blake3.create();
35
69
  for await (const chunk of readable) {
36
70
  await writer.write(chunk);
37
71
  hasher.update(chunk);
72
+ size += chunk.byteLength;
38
73
  }
39
74
  await writer.close();
40
75
  await done;
41
76
  const hash = hex.fromBytes(hasher.digest());
42
- await this.delete(hash);
43
- await this.#index.set(hash, id);
44
- return hash;
45
- }
46
- async #getFileId(hash) {
47
- return this.#index.get(hash);
48
- }
49
- async #needFileId(hash) {
50
- return got(await this.#getFileId(hash), `file not found by hash "${hash}"`);
51
- }
52
- async *keys() {
53
- yield* this.#index.keys();
77
+ return { hash, size };
54
78
  }
79
+ #finalizeWrite = queue(async (hash, id, size) => {
80
+ const existingId = await this.#getId(hash);
81
+ if (existingId) {
82
+ await this.#bucket.delete(id);
83
+ }
84
+ else {
85
+ await this.#ids.set(hash, id);
86
+ await this.#addSize(size);
87
+ }
88
+ });
89
+ #addSize = queue(async (sizeChange) => {
90
+ const oldStats = await this.stats();
91
+ await this.#stats.set({ ...oldStats, size: oldStats.size + sizeChange });
92
+ });
93
+ #selfClean = queue(async () => {
94
+ const now = Date.now();
95
+ const expiredIds = [];
96
+ for await (const [id, { created }] of this.#wip.entries({ limit: 64 })) {
97
+ const since = now - created;
98
+ const isExpired = since > time.days(7);
99
+ if (isExpired)
100
+ expiredIds.push(id);
101
+ }
102
+ await Promise.all(expiredIds.map(id => this.#bucket.delete(id)));
103
+ await this.#wip.del(...expiredIds);
104
+ });
55
105
  }
56
106
  //# sourceMappingURL=mammoth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mammoth.js","sourceRoot":"","sources":["../../s/core/mammoth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,GAAG,EAAE,GAAG,EAAC,MAAM,WAAW,CAAA;AAClC,OAAO,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAA;AAE9C,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAA;AAG7C,MAAM,OAAO,OAAO;IACnB,MAAM,CAAA;IACN,QAAQ,CAAA;IAER,YAAY,KAAiB,EAAE,OAAgB;QAC9C,IAAI,CAAC,MAAM,GAAG,KAAK,CAAA;QACnB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAU;QACnB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC7B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAU;QACpB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAU;QACpB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QACvC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAU;QACtB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QACtC,IAAI,EAAE,EAAE,CAAC;YACR,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAC/B,CAAC;IACF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAoC;QAC/C,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAA;QACrB,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAA;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAA;QACnD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAA;QACxC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAA;QAE9B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YACpC,MAAM,MAAM,CAAC,KAAK,CAAC,KAAgC,CAAC,CAAA;YACpD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACrB,CAAC;QAED,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QACpB,MAAM,IAAI,CAAA;QACV,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;QAC3C,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACvB,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAC/B,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAU;QAC1B,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAS,IAAI,CAAC,CAAA;IACrC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,IAAU;QAC3B,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,2BAA2B,IAAI,GAAG,CAAC,CAAA;IAC5E,CAAC;IAED,KAAK,CAAA,CAAE,IAAI;QACV,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;IAC1B,CAAC;CACD"}
1
+ {"version":3,"file":"mammoth.js","sourceRoot":"","sources":["../../s/core/mammoth.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { Iceberg, Id } from "./types.js";
2
- export declare class IcebergMemory implements Iceberg {
1
+ import { Bucket, Id } from "./types.js";
2
+ export declare class MemoryBucket implements Bucket {
3
3
  #private;
4
4
  has(id: Id): Promise<boolean>;
5
5
  size(id: Id): Promise<number>;
@@ -1,6 +1,6 @@
1
1
  import { bytes, got, nap } from "@e280/stz";
2
2
  import { relaxer } from "./utils/relaxer.js";
3
- export class IcebergMemory {
3
+ export class MemoryBucket {
4
4
  #map = new Map();
5
5
  async has(id) {
6
6
  return this.#map.has(id);
@@ -26,4 +26,4 @@ export class IcebergMemory {
26
26
  this.#map.set(id, payload);
27
27
  }
28
28
  }
29
- //# sourceMappingURL=iceberg-memory.js.map
29
+ //# sourceMappingURL=memory-bucket.js.map
@@ -0,0 +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"}
package/x/core/types.d.ts CHANGED
@@ -1,17 +1,12 @@
1
1
  export type Hash = string;
2
2
  export type Id = string;
3
- export type Iceberg = {
3
+ export type Bucket = {
4
4
  has(id: Id): Promise<boolean>;
5
5
  size(id: Id): Promise<number>;
6
6
  delete(id: Id): Promise<void>;
7
7
  read(id: Id): Promise<Blob>;
8
8
  write(id: Id, readable: ReadableStream<Uint8Array>): Promise<void>;
9
9
  };
10
- export type Glacier = {
11
- has(hash: Hash): Promise<boolean>;
12
- size(hash: Hash): Promise<number>;
13
- read(hash: Hash): Promise<Blob>;
14
- delete(hash: Hash): Promise<void>;
15
- write(readable: ReadableStream<Uint8Array>): Promise<Hash>;
16
- keys(): AsyncIterable<Hash>;
10
+ export type Stats = {
11
+ size: number;
17
12
  };
@@ -0,0 +1,10 @@
1
+ import { Bucket, Id } from "../core/types.js";
2
+ export declare class DiskBucket implements Bucket {
3
+ #private;
4
+ constructor(directory: string);
5
+ has(id: Id): Promise<boolean>;
6
+ size(id: Id): Promise<number>;
7
+ delete(id: Id): Promise<void>;
8
+ read(id: Id): Promise<Blob>;
9
+ write(id: Id, readable: ReadableStream<Uint8Array>): Promise<void>;
10
+ }
@@ -0,0 +1,47 @@
1
+ import { join } from "node:path";
2
+ import { Readable } from "node:stream";
3
+ import { pipeline } from "node:stream/promises";
4
+ import { mkdir, stat, unlink } from "node:fs/promises";
5
+ import { createWriteStream, openAsBlob } from "node:fs";
6
+ import { isNotFound } from "./utils/is-not-found.js";
7
+ export class DiskBucket {
8
+ #directory;
9
+ constructor(directory) {
10
+ this.#directory = directory;
11
+ }
12
+ async has(id) {
13
+ try {
14
+ await stat(this.#path(id));
15
+ return true;
16
+ }
17
+ catch (error) {
18
+ if (isNotFound(error))
19
+ return false;
20
+ throw error;
21
+ }
22
+ }
23
+ async size(id) {
24
+ const stats = await stat(this.#path(id));
25
+ return stats.size;
26
+ }
27
+ async delete(id) {
28
+ try {
29
+ await unlink(this.#path(id));
30
+ }
31
+ catch (error) {
32
+ if (!isNotFound(error))
33
+ throw error;
34
+ }
35
+ }
36
+ async read(id) {
37
+ return openAsBlob(this.#path(id));
38
+ }
39
+ async write(id, readable) {
40
+ await mkdir(this.#directory, { recursive: true });
41
+ await pipeline(Readable.fromWeb(readable), createWriteStream(this.#path(id)));
42
+ }
43
+ #path(id) {
44
+ return join(this.#directory, id);
45
+ }
46
+ }
47
+ //# sourceMappingURL=disk-bucket.js.map
@@ -0,0 +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"}
@@ -0,0 +1,2 @@
1
+ export * from "../core/index.js";
2
+ export * from "./disk-bucket.js";
@@ -0,0 +1,3 @@
1
+ export * from "../core/index.js";
2
+ export * from "./disk-bucket.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../s/node/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1 @@
1
+ export declare function isNotFound(error: unknown): error is NodeJS.ErrnoException;
@@ -0,0 +1,6 @@
1
+ export function isNotFound(error) {
2
+ return (error instanceof Error
3
+ && "code" in error
4
+ && error.code === "ENOENT");
5
+ }
6
+ //# sourceMappingURL=is-not-found.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-not-found.js","sourceRoot":"","sources":["../../../s/node/utils/is-not-found.ts"],"names":[],"mappings":"AACA,MAAM,UAAU,UAAU,CAAC,KAAc;IACxC,OAAO,CACN,KAAK,YAAY,KAAK;WACnB,MAAM,IAAI,KAAK;WACf,KAAK,CAAC,IAAI,KAAK,QAAQ,CAC1B,CAAA;AACF,CAAC"}
package/x/test.js CHANGED
@@ -1,18 +1,30 @@
1
1
  import { Kv } from "@e280/kv";
2
+ import { rm } from "fs/promises";
2
3
  import { bytes, collect } from "@e280/stz";
3
4
  import { science, test, expect } from "@e280/science";
4
5
  import { Mammoth } from "./core/mammoth.js";
6
+ import { DiskBucket } from "./node/disk-bucket.js";
5
7
  import { randomId } from "./core/utils/random-id.js";
6
- import { IcebergMemory } from "./core/iceberg-memory.js";
8
+ import { MemoryBucket } from "./core/memory-bucket.js";
7
9
  const blob = () => new Blob([new Uint8Array([0xDE, 0xAD, 0xBE, 0xEF])]);
8
10
  const quickstream = (b) => new Blob([new Uint8Array(b)]).stream();
9
11
  function setup() {
10
- const index = new Kv();
11
- const iceberg = new IcebergMemory();
12
- const mammoth = new Mammoth(index, iceberg);
12
+ const manifest = new Kv();
13
+ const bucket = new MemoryBucket();
14
+ const mammoth = new Mammoth(manifest, bucket);
13
15
  return { mammoth };
14
16
  }
15
17
  await science.run({
18
+ "mammoth node": test(async () => {
19
+ const dataDir = "data";
20
+ await rm(dataDir, { recursive: true, force: true });
21
+ const manifest = new Kv();
22
+ const bucket = new DiskBucket(dataDir);
23
+ const mammoth = new Mammoth(manifest, bucket);
24
+ const hash = await mammoth.write(blob().stream());
25
+ const second = await mammoth.read(hash);
26
+ expect(bytes.eq(await second.bytes(), await blob().bytes()));
27
+ }),
16
28
  "mammoth": {
17
29
  ".write and .read": test(async () => {
18
30
  const { mammoth } = setup();
@@ -24,7 +36,7 @@ await science.run({
24
36
  const { mammoth } = setup();
25
37
  const hashA = await mammoth.write(blob().stream());
26
38
  const hashB = await mammoth.write(blob().stream());
27
- const keys = await collect(mammoth.keys());
39
+ const keys = await collect(mammoth.hashes());
28
40
  expect(hashA).is(hashB);
29
41
  expect(keys.length).is(1);
30
42
  expect(keys[0]).is(hashA);
@@ -40,7 +52,19 @@ await science.run({
40
52
  const hashA = await mammoth.write(quickstream([0xC0, 0xFF, 0xEE]));
41
53
  const hashB = await mammoth.write(quickstream([0xB0, 0x0B, 0x1E, 0x5]));
42
54
  expect(hashA).not.is(hashB);
43
- expect((await collect(mammoth.keys())).length).is(2);
55
+ expect((await collect(mammoth.hashes())).length).is(2);
56
+ }),
57
+ ".stats": test(async () => {
58
+ const { mammoth } = setup();
59
+ expect(await mammoth.stats()).deep({ size: 0 });
60
+ const hashA = await mammoth.write(quickstream([0xC0, 0xFF, 0xEE]));
61
+ expect(await mammoth.stats()).deep({ size: 3 });
62
+ const hashB = await mammoth.write(quickstream([0xB0, 0x0B, 0x1E, 0x5]));
63
+ expect(await mammoth.stats()).deep({ size: 7 });
64
+ await mammoth.delete(hashA);
65
+ expect(await mammoth.stats()).deep({ size: 4 });
66
+ await mammoth.delete(hashB);
67
+ expect(await mammoth.stats()).deep({ size: 0 });
44
68
  }),
45
69
  ".has": test(async () => {
46
70
  const { mammoth } = setup();
@@ -58,7 +82,7 @@ await science.run({
58
82
  const hash = await mammoth.write(blob().stream());
59
83
  await mammoth.delete(hash);
60
84
  expect(await mammoth.has(hash)).is(false);
61
- expect(await collect(mammoth.keys())).deep([]);
85
+ expect(await collect(mammoth.hashes())).deep([]);
62
86
  }),
63
87
  ".delete idempotent": test(async () => {
64
88
  const { mammoth } = setup();
@@ -67,7 +91,7 @@ await science.run({
67
91
  ".keys": test(async () => {
68
92
  const { mammoth } = setup();
69
93
  const hash = await mammoth.write(blob().stream());
70
- const keys = await collect(mammoth.keys());
94
+ const keys = await collect(mammoth.hashes());
71
95
  expect(keys.length).is(1);
72
96
  expect(keys[0]).is(hash);
73
97
  }),
package/x/test.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"test.js","sourceRoot":"","sources":["../s/test.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,EAAE,EAAC,MAAM,UAAU,CAAA;AAC3B,OAAO,EAAC,KAAK,EAAE,OAAO,EAAC,MAAM,WAAW,CAAA;AACxC,OAAO,EAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAC,MAAM,eAAe,CAAA;AAEnD,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAA;AAClD,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAA;AAEtD,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;AACvE,MAAM,WAAW,GAAG,CAAC,CAAW,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;AAE3E,SAAS,KAAK;IACb,MAAM,KAAK,GAAG,IAAI,EAAE,EAAU,CAAA;IAC9B,MAAM,OAAO,GAAG,IAAI,aAAa,EAAE,CAAA;IACnC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAC3C,OAAO,EAAC,OAAO,EAAC,CAAA;AACjB,CAAC;AAED,MAAM,OAAO,CAAC,GAAG,CAAC;IACjB,SAAS,EAAE;QACV,kBAAkB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;YAClC,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,EAAE,CAAA;YACzB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;YACjD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACvC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;QAC7D,CAAC,CAAC;QAEF,sBAAsB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;YACtC,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,EAAE,CAAA;YACzB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;YAClD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;YAClD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;YAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;YACvB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;QAC1B,CAAC,CAAC;QAEF,mBAAmB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;YACnC,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,EAAE,CAAA;YACzB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;YACrD,MAAM,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACtC,MAAM,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC9C,CAAC,CAAC;QAEF,uBAAuB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;YACvC,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,EAAE,CAAA;YACzB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YAClE,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;YACvE,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;YAC3B,MAAM,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACrD,CAAC,CAAC;QAEF,MAAM,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;YACtB,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,EAAE,CAAA;YACzB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;YACjD,MAAM,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;YACxC,MAAM,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;QAChD,CAAC,CAAC;QAEF,OAAO,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;YACvB,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,EAAE,CAAA;YACzB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;YACjD,MAAM,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACvC,CAAC,CAAC;QAEF,SAAS,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;YACzB,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,EAAE,CAAA;YACzB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;YACjD,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;YAC1B,MAAM,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;YACzC,MAAM,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC/C,CAAC,CAAC;QAEF,oBAAoB,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;YACpC,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,EAAE,CAAA;YACzB,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;QACjC,CAAC,CAAC;QAEF,OAAO,EAAE,IAAI,CAAC,KAAK,IAAG,EAAE;YACvB,MAAM,EAAC,OAAO,EAAC,GAAG,KAAK,EAAE,CAAA;YACzB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC,CAAA;YACjD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;YAC1C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACzB,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;QACzB,CAAC,CAAC;KACF;CACD,CAAC,CAAA"}
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../s/test.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"iceberg-opfs.js","sourceRoot":"","sources":["../../s/browser/iceberg-opfs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,UAAU,EAAC,MAAM,yBAAyB,CAAA;AAElD,MAAM,OAAO,WAAW;IACvB,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 +0,0 @@
1
- {"version":3,"file":"iceberg-memory.js","sourceRoot":"","sources":["../../s/core/iceberg-memory.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,aAAa;IACzB,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"}