@thi.ng/block-fs 0.4.4 → 0.5.1
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 +7 -1
- package/README.md +7 -1
- package/cli.js +32 -14
- package/fs.js +1 -0
- package/index.d.ts +0 -1
- package/index.js +0 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2025-06-
|
|
3
|
+
- **Last updated**: 2025-06-24T21:39:38Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -11,6 +11,12 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
11
11
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
12
12
|
and/or version bumps of transitive dependencies.
|
|
13
13
|
|
|
14
|
+
## [0.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/block-fs@0.5.0) (2025-06-18)
|
|
15
|
+
|
|
16
|
+
#### 🚀 Features
|
|
17
|
+
|
|
18
|
+
- update block count estimation, add more logging ([02c8037](https://github.com/thi-ng/umbrella/commit/02c8037))
|
|
19
|
+
|
|
14
20
|
### [0.4.1](https://github.com/thi-ng/umbrella/tree/@thi.ng/block-fs@0.4.1) (2025-04-16)
|
|
15
21
|
|
|
16
22
|
#### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -48,6 +48,12 @@ storage providers are included:
|
|
|
48
48
|
- [FileBlockStorage](https://docs.thi.ng/umbrella/block-fs/classes/FileBlockStorage.html):
|
|
49
49
|
Host-filesystem based blocks (one block per file)
|
|
50
50
|
|
|
51
|
+
> [IMPORTANT]
|
|
52
|
+
> For browser-compatibility reasons, the `FileBlockStorage` is NOT exposed when
|
|
53
|
+
> using package-level imports. Use the following import to use this class:
|
|
54
|
+
>
|
|
55
|
+
> `import { FileBlockStorage } from "@thi.ng/block-fs/storage/file";
|
|
56
|
+
|
|
51
57
|
As the name indicates, block storage providers only support block-based
|
|
52
58
|
read/write/delete access to arbitrary binary data (all ops are async). For
|
|
53
59
|
file-based storage, blocks are created lazily/dynamically.
|
|
@@ -288,7 +294,7 @@ For Node.js REPL:
|
|
|
288
294
|
const bf = await import("@thi.ng/block-fs");
|
|
289
295
|
```
|
|
290
296
|
|
|
291
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 4.
|
|
297
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 4.29 KB
|
|
292
298
|
|
|
293
299
|
## Dependencies
|
|
294
300
|
|
package/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ import { illegalArgs } from "@thi.ng/errors";
|
|
|
10
10
|
import { files, readBinary, readJSON, writeFile } from "@thi.ng/file-io";
|
|
11
11
|
import { LogLevel } from "@thi.ng/logger";
|
|
12
12
|
import { statSync } from "node:fs";
|
|
13
|
-
import {
|
|
13
|
+
import { join, relative, resolve } from "node:path";
|
|
14
14
|
import { Entry } from "./entry.js";
|
|
15
15
|
import { BlockFS } from "./fs.js";
|
|
16
16
|
import { MemoryBlockStorage } from "./storage/memory.js";
|
|
@@ -28,6 +28,14 @@ const ARG_BLOCKSIZE = {
|
|
|
28
28
|
}
|
|
29
29
|
})
|
|
30
30
|
};
|
|
31
|
+
const requiredBytes = (x) => align(Math.ceil(Math.log2(x)), 8) >> 3;
|
|
32
|
+
const pathsForFile = (f) => {
|
|
33
|
+
const parts = f.split("/");
|
|
34
|
+
const dirs = [];
|
|
35
|
+
for (let i = 1; i < parts.length; i++)
|
|
36
|
+
dirs.push(parts.slice(0, i).join("/"));
|
|
37
|
+
return dirs;
|
|
38
|
+
};
|
|
31
39
|
const collectFiles = ({
|
|
32
40
|
opts: { include, exclude },
|
|
33
41
|
inputs
|
|
@@ -50,24 +58,30 @@ const collectFiles = ({
|
|
|
50
58
|
ctime: stats.ctimeMs,
|
|
51
59
|
mtime: stats.mtimeMs
|
|
52
60
|
});
|
|
53
|
-
dirs.add(
|
|
61
|
+
for (let d of pathsForFile(dest)) dirs.add(d);
|
|
54
62
|
total += stats.size;
|
|
55
63
|
}
|
|
56
64
|
return { files: filtered, dirs: [...dirs], size: total };
|
|
57
65
|
};
|
|
58
|
-
const computeBlockCount = (collected, blockSize, numBlocks) => {
|
|
66
|
+
const computeBlockCount = (collected, blockSize, logger, numBlocks) => {
|
|
59
67
|
let blocks = collected.dirs.length;
|
|
60
|
-
const blockIDBytes =
|
|
61
|
-
|
|
62
|
-
const blockDataSize = blockSize - blockIDBytes - blockDataSizeBytes;
|
|
63
|
-
blocks += Math.ceil(
|
|
64
|
-
(collected.files.length + collected.dirs.length) * Entry.SIZE / blockDataSize
|
|
68
|
+
const blockIDBytes = requiredBytes(
|
|
69
|
+
numBlocks ?? collected.size / blockSize + blocks
|
|
65
70
|
);
|
|
71
|
+
const blockDataSizeBytes = requiredBytes(blockSize);
|
|
72
|
+
const blockDataSize = blockSize - blockIDBytes - blockDataSizeBytes;
|
|
73
|
+
const numEntries = collected.files.length + collected.dirs.length;
|
|
74
|
+
const numEntryBlocks = Math.ceil(numEntries * Entry.SIZE / blockDataSize);
|
|
75
|
+
logger.info("num entries:", numEntries);
|
|
76
|
+
logger.info("num entry blocks:", numEntryBlocks);
|
|
77
|
+
blocks += numEntryBlocks;
|
|
66
78
|
for (let f of collected.files) {
|
|
67
|
-
|
|
79
|
+
const size = Math.ceil(f.size / blockDataSize);
|
|
80
|
+
logger.debug("file:", f.src, "blocks:", size);
|
|
81
|
+
blocks += size;
|
|
68
82
|
}
|
|
69
|
-
const blockIDBytes2 =
|
|
70
|
-
return blockIDBytes2 > blockIDBytes ? computeBlockCount(collected, blockSize, blocks) : blocks;
|
|
83
|
+
const blockIDBytes2 = requiredBytes(blocks);
|
|
84
|
+
return blockIDBytes2 > blockIDBytes ? computeBlockCount(collected, blockSize, logger, blocks) : blocks;
|
|
71
85
|
};
|
|
72
86
|
const CONVERT = {
|
|
73
87
|
opts: {
|
|
@@ -97,7 +111,7 @@ const CONVERT = {
|
|
|
97
111
|
fn: async (ctx) => {
|
|
98
112
|
const collected = collectFiles(ctx);
|
|
99
113
|
const numBlocks = align(
|
|
100
|
-
ctx.opts.numBlocks ?? computeBlockCount(collected, ctx.opts.blockSize),
|
|
114
|
+
ctx.opts.numBlocks ?? computeBlockCount(collected, ctx.opts.blockSize, ctx.logger),
|
|
101
115
|
8
|
|
102
116
|
);
|
|
103
117
|
ctx.logger.info("number of files:", collected.files.length);
|
|
@@ -111,9 +125,13 @@ const CONVERT = {
|
|
|
111
125
|
});
|
|
112
126
|
const bfs = new BlockFS(storage, { logger: ctx.logger });
|
|
113
127
|
await bfs.init();
|
|
128
|
+
ctx.logger.info("root dir block:", bfs.rootDirBlockID);
|
|
129
|
+
ctx.logger.info("first data block:", bfs.dataStartBlockID);
|
|
130
|
+
ctx.logger.info("block data size:", bfs.blockDataSize);
|
|
114
131
|
for (let f of collected.files) {
|
|
115
|
-
|
|
116
|
-
|
|
132
|
+
const data = readBinary(f.src, ctx.logger);
|
|
133
|
+
ctx.logger.info("writing file:", f.dest, "size:", data.length);
|
|
134
|
+
await bfs.writeFile(f.dest, data);
|
|
117
135
|
const entry = await bfs.entryForPath(f.dest);
|
|
118
136
|
entry.ctime = f.ctime;
|
|
119
137
|
entry.mtime = f.mtime;
|
package/fs.js
CHANGED
|
@@ -323,6 +323,7 @@ class BlockFS {
|
|
|
323
323
|
async writeBlocks(blocks, data) {
|
|
324
324
|
const { blockDataOffset, blockDataSize, sentinelID, storage } = this;
|
|
325
325
|
if (!blocks) blocks = await this.allocateBlocks(data.length);
|
|
326
|
+
this.opts.logger.debug("allocated blocks", blocks.length, blocks);
|
|
326
327
|
let offset = 0;
|
|
327
328
|
for (let i = 0, numBlocks = blocks.length - 1; i <= numBlocks; i++) {
|
|
328
329
|
if (offset >= data.length)
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/block-fs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Customizable block-based storage, adapters & file system layer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -43,16 +43,16 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@thi.ng/api": "^8.11.29",
|
|
46
|
-
"@thi.ng/args": "^2.3.
|
|
46
|
+
"@thi.ng/args": "^2.3.71",
|
|
47
47
|
"@thi.ng/binary": "^3.4.52",
|
|
48
|
-
"@thi.ng/bitfield": "^2.4.
|
|
48
|
+
"@thi.ng/bitfield": "^2.4.5",
|
|
49
49
|
"@thi.ng/checks": "^3.7.9",
|
|
50
50
|
"@thi.ng/errors": "^2.5.35",
|
|
51
51
|
"@thi.ng/file-io": "^2.1.38",
|
|
52
52
|
"@thi.ng/logger": "^3.1.10",
|
|
53
53
|
"@thi.ng/mime": "^2.7.11",
|
|
54
54
|
"@thi.ng/random": "^4.1.20",
|
|
55
|
-
"@thi.ng/strings": "^3.9.
|
|
55
|
+
"@thi.ng/strings": "^3.9.15"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/node": "^22.15.21",
|
|
@@ -132,5 +132,5 @@
|
|
|
132
132
|
"status": "alpha",
|
|
133
133
|
"year": 2024
|
|
134
134
|
},
|
|
135
|
-
"gitHead": "
|
|
135
|
+
"gitHead": "45e91ee75236e39fc87ea10fbabac1272bef62e3\n"
|
|
136
136
|
}
|