functionalscript 0.33.0 → 0.35.0
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 +27 -14
- package/fs/asserts/module.f.d.ts +1 -1
- package/fs/asserts/module.f.js +4 -1
- package/fs/base64/proof.f.d.ts +1 -0
- package/fs/base64/proof.f.js +25 -56
- package/fs/base_n/module.f.js +11 -5
- package/fs/base_n/proof.f.d.ts +1 -0
- package/fs/base_n/proof.f.js +12 -1
- package/fs/bnf/data/module.f.d.ts +0 -103
- package/fs/bnf/data/module.f.js +10 -246
- package/fs/bnf/data/proof.f.d.ts +0 -10
- package/fs/bnf/data/proof.f.js +2 -642
- package/fs/bnf/descent/module.f.d.ts +56 -0
- package/fs/bnf/descent/module.f.js +119 -0
- package/fs/bnf/descent/proof.f.d.ts +5 -0
- package/fs/bnf/descent/proof.f.js +296 -0
- package/fs/bnf/ll1/module.f.d.ts +72 -0
- package/fs/bnf/ll1/module.f.js +153 -0
- package/fs/bnf/ll1/proof.f.d.ts +9 -0
- package/fs/bnf/ll1/proof.f.js +358 -0
- package/fs/cas/cli/module.f.d.ts +6 -0
- package/fs/cas/cli/module.f.js +56 -0
- package/fs/cas/cli/proof.f.d.ts +14 -0
- package/fs/cas/cli/proof.f.js +149 -0
- package/fs/cas/mcp/module.f.d.ts +9 -17
- package/fs/cas/mcp/module.f.js +123 -96
- package/fs/cas/mcp/proof.f.d.ts +12 -1
- package/fs/cas/mcp/proof.f.js +199 -32
- package/fs/cas/module.f.d.ts +35 -15
- package/fs/cas/module.f.js +168 -131
- package/fs/cas/proof.f.d.ts +16 -13
- package/fs/cas/proof.f.js +255 -121
- package/fs/ci/config/module.f.d.ts +14 -14
- package/fs/ci/config/module.f.js +14 -14
- package/fs/djs/tokenizer-new/module.f.js +1 -1
- package/fs/djs/tokenizer-new/proof.f.d.ts +2 -0
- package/fs/djs/tokenizer-new/proof.f.js +357 -229
- package/fs/effects/list/module.f.d.ts +31 -0
- package/fs/effects/list/module.f.js +16 -0
- package/fs/effects/module.f.d.ts +11 -5
- package/fs/effects/module.f.js +16 -6
- package/fs/effects/node/module.f.d.ts +29 -3
- package/fs/effects/node/module.f.js +35 -1
- package/fs/effects/node/module.js +32 -18
- package/fs/effects/node/virtual/module.f.js +57 -0
- package/fs/effects/proof.f.d.ts +4 -0
- package/fs/effects/proof.f.js +18 -1
- package/fs/fjs/module.f.js +2 -8
- package/fs/html/module.f.js +6 -8
- package/fs/mcp/module.f.d.ts +1 -1
- package/fs/mcp/stdio/module.f.d.ts +8 -0
- package/fs/mcp/stdio/module.f.js +33 -6
- package/fs/mcp/stdio/proof.f.d.ts +3 -0
- package/fs/mcp/stdio/proof.f.js +52 -1
- package/fs/mime/module.f.d.ts +101 -5
- package/fs/mime/module.f.js +159 -6
- package/fs/mime/proof.f.d.ts +25 -0
- package/fs/mime/proof.f.js +193 -3
- package/fs/text/code_point/module.f.d.ts +39 -2
- package/fs/text/code_point/module.f.js +74 -2
- package/fs/text/code_point/proof.f.d.ts +8 -0
- package/fs/text/code_point/proof.f.js +72 -0
- package/fs/text/module.f.d.ts +11 -1
- package/fs/text/module.f.js +13 -3
- package/fs/text/proof.f.d.ts +6 -0
- package/fs/text/proof.f.js +25 -2
- package/fs/text/utf16/module.f.js +4 -26
- package/fs/text/utf8/module.f.d.ts +27 -0
- package/fs/text/utf8/module.f.js +8 -14
- package/fs/types/bit_vec/module.f.d.ts +20 -2
- package/fs/types/bit_vec/module.f.js +77 -27
- package/fs/types/bit_vec/proof.f.d.ts +8 -0
- package/fs/types/bit_vec/proof.f.js +24 -6
- package/fs/types/function/operator/module.f.d.ts +26 -0
- package/fs/types/list/module.f.d.ts +3 -0
- package/fs/types/nullable/module.f.d.ts +9 -5
- package/fs/types/nullable/module.f.js +19 -0
- package/fs/types/result/module.d.ts +2 -4
- package/fs/types/result/module.js +9 -3
- package/package.json +3 -3
- package/issues/demo/data/data.f.js +0 -12
- package/issues/demo/data/shared.f.js +0 -3
- package/issues/demo/fs/app.js +0 -4
- package/issues/demo/fs/math.f.js +0 -4
- package/issues/demo/sample/proof.f.js +0 -13
- /package/{issues → todo}/031-json.f.d.ts +0 -0
- /package/{issues → todo}/031-json.f.js +0 -0
- /package/{issues → todo}/proof.f.d.ts +0 -0
- /package/{issues → todo}/proof.f.js +0 -0
package/fs/cas/module.f.js
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { sha256 } from "../crypto/sha2/module.f.js";
|
|
7
7
|
import { join, normalize, parse } from "../path/module.f.js";
|
|
8
8
|
import { empty, length, maxLengthBytes, msb, vec } from "../types/bit_vec/module.f.js";
|
|
9
9
|
import { cBase32ToVec, vecToCBase32 } from "../cbase32/module.f.js";
|
|
10
10
|
import { foldStep, forEachStep, pure } from "../effects/module.f.js";
|
|
11
|
-
import { access,
|
|
12
|
-
import { dispatch } from "../cli/module.f.js";
|
|
11
|
+
import { access, createExclusive, isNotFound, mkdir, now, randomInt, readBytes, readdir, rename, rm, stat, writeBytes, } from "../effects/node/module.f.js";
|
|
13
12
|
import { toOption } from "../types/nullable/module.f.js";
|
|
14
13
|
import { error, ok, unwrap } from "../types/result/module.f.js";
|
|
15
14
|
import { splitAt } from "../types/string/module.f.js";
|
|
15
|
+
import { nonEmpty, empty as elEmpty } from "../effects/list/module.f.js";
|
|
16
16
|
const split2 = splitAt(2);
|
|
17
17
|
const prefix = '.cas';
|
|
18
18
|
/** Converts a content key to its sharded relative CAS file path. */
|
|
@@ -22,151 +22,188 @@ export const toPath = (key) => {
|
|
|
22
22
|
const [b, c] = split2(bc);
|
|
23
23
|
return join(prefix, a, b, c);
|
|
24
24
|
};
|
|
25
|
+
/** Maximum chunk size for streaming reads: the largest `Vec` the runtime allows. */
|
|
26
|
+
const chunkBytes = Number(maxLengthBytes);
|
|
27
|
+
/** Staging directory under the store root; GC and every uploader share it. */
|
|
28
|
+
const stageRel = '_stage';
|
|
29
|
+
/**
|
|
30
|
+
* Lease duration in ms: a staging file's deadline is `now() + leaseDelta`.
|
|
31
|
+
* Renewed after every chunk, so it only has to cover the gap between two
|
|
32
|
+
* consecutive chunks (see [staging-lease.md](../../issues/cas/staging-lease.md)).
|
|
33
|
+
*/
|
|
34
|
+
const leaseDelta = 30_000;
|
|
35
|
+
/**
|
|
36
|
+
* Fixed width for the zero-padded epoch-ms deadline embedded in a staging name,
|
|
37
|
+
* so names sort lexically exactly as they sort chronologically. 19 digits keeps
|
|
38
|
+
* epoch-ms (13 digits today) padded with headroom well past year 2286.
|
|
39
|
+
*/
|
|
40
|
+
const deadlineWidth = 19;
|
|
41
|
+
/** Builds a `<deadline>-<random256>` staging file name. */
|
|
42
|
+
const stageName = (deadline, rnd) => `${String(deadline).padStart(deadlineWidth, '0')}-${rnd}`;
|
|
43
|
+
/** Recovers the deadline (epoch ms) from a `<deadline>-<random256>` name. */
|
|
44
|
+
const deadlineOf = (name) => Number(name.slice(0, name.indexOf('-')));
|
|
45
|
+
/**
|
|
46
|
+
* Reclaims expired staging files: any `_stage/<deadline>-<rand>` whose deadline
|
|
47
|
+
* is already in the past. Lazy and piggy-backed on `write`. Best-effort — a
|
|
48
|
+
* missing `_stage/` (fresh store) or any `readdir`/`rm` error is ignored, and a
|
|
49
|
+
* still-live lease is left alone; the fencing rename keeps even a misjudged
|
|
50
|
+
* reclaim fail-safe (worst case: that upload restarts).
|
|
51
|
+
*/
|
|
52
|
+
const gcStage = (stageDir) => now().step(t => readdir(stageDir, {}).step(([k, v]) => {
|
|
53
|
+
if (k === 'error') {
|
|
54
|
+
return pure(undefined);
|
|
55
|
+
}
|
|
56
|
+
const expired = v.flatMap(d => d.isFile && deadlineOf(d.name) < t ? [d.name] : []);
|
|
57
|
+
return forEachStep((name) => rm(join(stageDir, name)).step(() => pure(undefined)))(expired);
|
|
58
|
+
}));
|
|
25
59
|
/**
|
|
26
60
|
* Builds a content-addressable storage facade from a SHA-2 implementation.
|
|
27
61
|
*/
|
|
28
|
-
export const fileCas = (sha2) => {
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
export const fileCas = (sha2) => (path) => {
|
|
63
|
+
const storePrefix = join(path, prefix);
|
|
64
|
+
const normalizedStorePrefix = normalize(storePrefix);
|
|
65
|
+
const stageDir = join(storePrefix, stageRel);
|
|
66
|
+
return {
|
|
67
|
+
read: (hash) => {
|
|
68
|
+
const p = join(path, toPath(hash));
|
|
69
|
+
const loop = (offset) => readBytes(p, offset, chunkBytes)
|
|
70
|
+
.step((result) => {
|
|
71
|
+
const [t, v] = result;
|
|
72
|
+
// A missing shard or read error is an explicit error item, never EOF.
|
|
73
|
+
if (t === 'error') {
|
|
74
|
+
return nonEmpty(result, elEmpty());
|
|
75
|
+
}
|
|
76
|
+
// End the stream only on an empty read; every non-empty read — including a
|
|
77
|
+
// final short (`< CHUNK_BYTES`) chunk — is emitted as an `ok` item.
|
|
78
|
+
return length(v) === 0n
|
|
79
|
+
? elEmpty()
|
|
80
|
+
: nonEmpty(ok(v), loop(offset + chunkBytes));
|
|
81
|
+
});
|
|
82
|
+
return loop(0);
|
|
83
|
+
},
|
|
84
|
+
// Lock-free staging upload (issues/cas/staging-lease.md): stream each chunk straight
|
|
85
|
+
// to a `_stage/<deadline>-<rand>` file via `writeBytes` while folding it into the
|
|
86
|
+
// running SHA-2 state — the payload never lives in memory as a whole. The lease is
|
|
87
|
+
// renewed (rename to a fresh deadline) after every chunk; any error deletes the
|
|
88
|
+
// partial file and fails. On end-of-stream the file is published to its hash-derived
|
|
89
|
+
// shard path by a replace-`rename` (which also dedups/repairs a same-content shard),
|
|
90
|
+
// and success is confirmed by a `stat` size check. GC of expired staging files is
|
|
91
|
+
// piggy-backed at the start.
|
|
92
|
+
write: (payload) => {
|
|
93
|
+
// Publish the finished staging file to its content-addressed shard. The three
|
|
94
|
+
// filesystem steps run best-effort with their results ignored; success is decided
|
|
95
|
+
// afterward by observing the target's size (see staging-lease.md "Publish ignores
|
|
96
|
+
// results and checks the end state").
|
|
97
|
+
const publish = (state, offset, curPath) => {
|
|
98
|
+
const hash = sha2.end(state);
|
|
99
|
+
const rel = toPath(hash);
|
|
100
|
+
const dst = join(path, rel);
|
|
101
|
+
const dstDir = join(path, ...parse(rel).slice(0, -1));
|
|
102
|
+
return mkdir(dstDir, { recursive: true })
|
|
103
|
+
.step(() => rename(curPath, dst))
|
|
104
|
+
.step(() => rm(curPath))
|
|
105
|
+
.step(() => stat(dst))
|
|
106
|
+
.step(st => pure(st[0] === 'ok' && st[1].size === offset ? ok(hash) : error('publish size mismatch')));
|
|
107
|
+
};
|
|
108
|
+
// Any streaming error fails closed: delete the partial file, return the error.
|
|
109
|
+
const fail = (curPath, e) => rm(curPath).step(() => pure(error(e)));
|
|
110
|
+
return gcStage(stageDir).step(() => random256.step(rnd => {
|
|
111
|
+
const rndStr = vecToCBase32(rnd);
|
|
112
|
+
const loop = (state, offset, curPath) => (stream) => stream
|
|
113
|
+
.step((node) => {
|
|
114
|
+
if (node === undefined) {
|
|
115
|
+
return publish(state, offset, curPath);
|
|
55
116
|
}
|
|
56
|
-
|
|
117
|
+
const { first, tail } = node;
|
|
118
|
+
if (first[0] === 'error') {
|
|
119
|
+
return fail(curPath, first[1]);
|
|
120
|
+
}
|
|
121
|
+
const chunk = first[1];
|
|
122
|
+
return writeBytes(curPath, offset, chunk)
|
|
123
|
+
.step(wb => {
|
|
124
|
+
if (wb[0] === 'error') {
|
|
125
|
+
return fail(curPath, wb[1]);
|
|
126
|
+
}
|
|
127
|
+
const newState = sha2.append(chunk)(state);
|
|
128
|
+
const newOffset = offset + Number(length(chunk) / 8n);
|
|
129
|
+
// Renew the lease: rename to a fresh deadline (keeps `delta` constant).
|
|
130
|
+
return now()
|
|
131
|
+
.step(t => {
|
|
132
|
+
const next = join(stageDir, stageName(t + leaseDelta, rndStr));
|
|
133
|
+
return rename(curPath, next).step(([t, v]) => t === 'error'
|
|
134
|
+
? fail(curPath, v)
|
|
135
|
+
: loop(newState, newOffset, next)(tail));
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
return mkdir(stageDir, { recursive: true })
|
|
140
|
+
.step(() => now()
|
|
141
|
+
.step(t0 => {
|
|
142
|
+
const path0 = join(stageDir, stageName(t0 + leaseDelta, rndStr));
|
|
143
|
+
return createExclusive(path0)
|
|
144
|
+
.step(([c, e]) => c === 'error'
|
|
145
|
+
? pure(error(e))
|
|
146
|
+
: loop(sha2.init, 0, path0)(payload));
|
|
147
|
+
}));
|
|
148
|
+
}));
|
|
149
|
+
},
|
|
150
|
+
list: () =>
|
|
151
|
+
// A fresh store has no `.cas` directory yet. Treat *only* that case as an
|
|
152
|
+
// empty store, mirroring how `read` maps a missing shard to an error item.
|
|
153
|
+
// A `.cas` that exists but cannot be read (permissions, corruption) is a
|
|
154
|
+
// genuine storage error and is surfaced, not masked as "no hashes".
|
|
155
|
+
access(storePrefix).step(a => {
|
|
156
|
+
if (a[0] === 'error') {
|
|
157
|
+
if (isNotFound(a[1])) {
|
|
158
|
+
return pure([]);
|
|
57
159
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
160
|
+
throw a[1];
|
|
161
|
+
}
|
|
162
|
+
return readdir(storePrefix, { recursive: true })
|
|
163
|
+
.step(r => pure(unwrap(r).flatMap(({ name, parentPath, isFile }) => toOption(isFile
|
|
164
|
+
? cBase32ToVec(normalize(parentPath).substring(normalizedStorePrefix.length).replaceAll('/', '') + name)
|
|
165
|
+
: null))));
|
|
166
|
+
}),
|
|
167
|
+
url: (hash) => join(path, toPath(hash))
|
|
64
168
|
};
|
|
65
169
|
};
|
|
66
|
-
/** Maximum chunk size for streaming reads: the largest `Vec` the runtime allows. */
|
|
67
|
-
const CHUNK_BYTES = Number(maxLengthBytes);
|
|
68
170
|
/** 256-bit random `Vec` built from 8 sequential `randomInt` (32-bit) calls. */
|
|
69
171
|
const random256 = foldStep((_) => (acc) => randomInt().step(r => pure(msb.concat(acc)(vec(32n)(BigInt(r))))))(empty)([0, 1, 2, 3, 4, 5, 6, 7]);
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
*/
|
|
74
|
-
const streamHash = (sha2) => (path) => {
|
|
75
|
-
const chunkBits = BigInt(CHUNK_BYTES) * 8n;
|
|
76
|
-
const loop = (state, offset) => readBytes(path, offset, CHUNK_BYTES).step(result => {
|
|
172
|
+
/** Streams any file at `filePath` in `<=128 KiB` chunks as a `ListEffect` of `ok` items. */
|
|
173
|
+
const streamFile = (filePath) => {
|
|
174
|
+
const loop = (offset) => readBytes(filePath, offset, chunkBytes).step((result) => {
|
|
77
175
|
if (result[0] === 'error') {
|
|
78
|
-
return
|
|
176
|
+
return nonEmpty(result, elEmpty());
|
|
79
177
|
}
|
|
80
178
|
const chunk = result[1];
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
return loop(newState, offset + CHUNK_BYTES);
|
|
179
|
+
return length(chunk) === 0n
|
|
180
|
+
? elEmpty()
|
|
181
|
+
: nonEmpty(ok(chunk), loop(offset + chunkBytes));
|
|
86
182
|
});
|
|
87
|
-
return loop(
|
|
183
|
+
return loop(0);
|
|
88
184
|
};
|
|
89
185
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
186
|
+
* Streams the file at `path` through `cas.write`, returning the content hash.
|
|
187
|
+
* Both the CLI `cas add` and the MCP `add` delegate to this; the MCP layer
|
|
188
|
+
* additionally deletes the source file on success.
|
|
189
|
+
*/
|
|
190
|
+
export const casAddFile = (cas) => (path) =>
|
|
191
|
+
// streamFile produces only ReadBytes effects. TypeScript can't prove ListEffect<ReadBytes,T>
|
|
192
|
+
// ≤ ListEffect<O,T> for generic O (recursive type), but the cast is sound: every concrete
|
|
193
|
+
// caller passes a Cas<O> where ReadBytes ⊆ O (e.g. FileCasOperation).
|
|
194
|
+
cas.write(streamFile(path));
|
|
195
|
+
/**
|
|
196
|
+
* Upload pipeline: streams `fileName` from `~/cas_upload/` through `casAddFile`,
|
|
197
|
+
* then deletes the source on success. On failure the source is left in place so
|
|
198
|
+
* the upload can be retried; `write` already cleans up its own partial staging file.
|
|
93
199
|
*/
|
|
94
200
|
export const casUpload = (home) => (fileName) => {
|
|
95
201
|
const src = join(home, 'cas_upload', fileName);
|
|
96
|
-
const
|
|
97
|
-
return
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
.step(r => {
|
|
103
|
-
if (r[0] === 'error') {
|
|
104
|
-
return pure(error(r[1]));
|
|
105
|
-
}
|
|
106
|
-
return streamHash(sha256)(stagePath)
|
|
107
|
-
.step(hashResult => {
|
|
108
|
-
if (hashResult[0] === 'error') {
|
|
109
|
-
return pure(hashResult);
|
|
110
|
-
}
|
|
111
|
-
const hash = hashResult[1];
|
|
112
|
-
const p = toPath(hash);
|
|
113
|
-
const parts = parse(p);
|
|
114
|
-
const finalDir = join(home, ...parts.slice(0, -1));
|
|
115
|
-
const finalPath = join(home, p);
|
|
116
|
-
return mkdir(finalDir, { recursive: true })
|
|
117
|
-
.step(() => rename(stagePath, finalPath))
|
|
118
|
-
.step(r2 => pure(r2[0] === 'error' ? error(r2[1]) : ok(hash)));
|
|
119
|
-
});
|
|
120
|
-
});
|
|
202
|
+
const c = fileCas(sha256)(home);
|
|
203
|
+
return casAddFile(c)(src).step((result) => {
|
|
204
|
+
if (result[0] === 'error') {
|
|
205
|
+
return pure(result);
|
|
206
|
+
}
|
|
207
|
+
return rm(src).step(() => pure(result));
|
|
121
208
|
});
|
|
122
209
|
};
|
|
123
|
-
export const commands = [
|
|
124
|
-
{
|
|
125
|
-
names: ['add'],
|
|
126
|
-
description: 'Store file content and print its hash',
|
|
127
|
-
handler: ({ home, args: [path, ...rest] }) => {
|
|
128
|
-
if (path === undefined || rest.length !== 0) {
|
|
129
|
-
return errorExit("'cas add' expects one parameter");
|
|
130
|
-
}
|
|
131
|
-
const c = fileCas(sha256)(home);
|
|
132
|
-
return readFile(path)
|
|
133
|
-
.step(v => c.write(unwrap(v)))
|
|
134
|
-
.step(hash => hash === undefined
|
|
135
|
-
? pure(1)
|
|
136
|
-
: log(vecToCBase32(hash)).step(() => pure(0)));
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
names: ['get'],
|
|
141
|
-
description: 'Restore content by hash into a file',
|
|
142
|
-
handler: ({ home, args: [hashCBase32, path, ...rest] }) => {
|
|
143
|
-
if (hashCBase32 === undefined || path === undefined || rest.length !== 0) {
|
|
144
|
-
return errorExit("'cas get' expects two parameters");
|
|
145
|
-
}
|
|
146
|
-
const hash = cBase32ToVec(hashCBase32);
|
|
147
|
-
if (hash === null) {
|
|
148
|
-
return errorExit(`invalid hash format: ${hashCBase32}`);
|
|
149
|
-
}
|
|
150
|
-
const c = fileCas(sha256)(home);
|
|
151
|
-
return c.read(hash)
|
|
152
|
-
.step(v => {
|
|
153
|
-
const result = v === undefined
|
|
154
|
-
? errorExit(`no such hash: ${hashCBase32}`)
|
|
155
|
-
: writeFile(path, v)
|
|
156
|
-
.step(() => pure(0));
|
|
157
|
-
return result;
|
|
158
|
-
});
|
|
159
|
-
},
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
names: ['list'],
|
|
163
|
-
description: 'List all stored content hashes',
|
|
164
|
-
handler: ({ home }) => {
|
|
165
|
-
const c = fileCas(sha256)(home);
|
|
166
|
-
return c.list()
|
|
167
|
-
.step(forEachStep(j => log(vecToCBase32(j))))
|
|
168
|
-
.step(() => pure(0));
|
|
169
|
-
},
|
|
170
|
-
},
|
|
171
|
-
];
|
|
172
|
-
export const main = dispatch(commands);
|
package/fs/cas/proof.f.d.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
import { type FileCasOperation } from './module.f.ts';
|
|
2
|
+
import { type Effect } from '../effects/module.f.ts';
|
|
3
|
+
import { type ReadFile, type WriteFile, type Rm, type Mkdir } from '../effects/node/module.f.ts';
|
|
4
|
+
type TestOp = FileCasOperation | WriteFile | ReadFile | Rm | Mkdir;
|
|
1
5
|
export declare const proof: {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
casWrite: () => void;
|
|
14
|
-
casReadPassthrough: () => void;
|
|
6
|
+
addBigFile: () => Effect<TestOp, void>;
|
|
7
|
+
addAndGetBigFile: () => Effect<TestOp, void>;
|
|
8
|
+
casWriteRead: () => void;
|
|
9
|
+
casReadMissingShard: () => void;
|
|
10
|
+
casWriteMultiChunk: () => void;
|
|
11
|
+
casWriteDedup: () => void;
|
|
12
|
+
casWriteErrorItemAborts: () => void;
|
|
13
|
+
casWriteReadExceedsMaxLength: () => void;
|
|
14
|
+
casWriteGcReclaimsExpired: () => void;
|
|
15
|
+
casUploadSuccess: () => void;
|
|
16
|
+
casUploadFailureKeepsSource: () => void;
|
|
15
17
|
};
|
|
18
|
+
export {};
|