@effect-vfs/core 0.5.0 → 0.7.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 +29 -21
- package/dist/BytePath.d.ts +115 -4
- package/dist/BytePath.d.ts.map +1 -1
- package/dist/BytePath.js +155 -0
- package/dist/Caller.d.ts +391 -0
- package/dist/Caller.d.ts.map +1 -0
- package/dist/Caller.js +199 -0
- package/dist/FileHandle.d.ts +50 -0
- package/dist/FileHandle.d.ts.map +1 -0
- package/dist/FileHandle.js +28 -0
- package/dist/Fixture.d.ts +155 -0
- package/dist/Fixture.d.ts.map +1 -0
- package/dist/Fixture.js +65 -0
- package/dist/LiveVolume.d.ts +13 -20
- package/dist/LiveVolume.d.ts.map +1 -1
- package/dist/LiveVolume.js +19 -14
- package/dist/Metadata.d.ts +186 -0
- package/dist/Metadata.d.ts.map +1 -0
- package/dist/Metadata.js +125 -0
- package/dist/Snapshot.d.ts +32 -53
- package/dist/Snapshot.d.ts.map +1 -1
- package/dist/Snapshot.js +27 -49
- package/dist/SnapshotDelta.d.ts +24 -39
- package/dist/SnapshotDelta.d.ts.map +1 -1
- package/dist/SnapshotDelta.js +14 -35
- package/dist/Target.d.ts +225 -0
- package/dist/Target.d.ts.map +1 -0
- package/dist/Target.js +92 -0
- package/dist/Testing.d.ts +132 -0
- package/dist/Testing.d.ts.map +1 -0
- package/dist/Testing.js +100 -0
- package/dist/VfsError.d.ts +200 -0
- package/dist/VfsError.d.ts.map +1 -0
- package/dist/VfsError.js +165 -0
- package/dist/VirtualFileSystem.d.ts +676 -353
- package/dist/VirtualFileSystem.d.ts.map +1 -1
- package/dist/VirtualFileSystem.js +487 -121
- package/dist/Volume.d.ts +211 -0
- package/dist/Volume.d.ts.map +1 -0
- package/dist/Volume.js +172 -0
- package/dist/Watch.d.ts +68 -0
- package/dist/Watch.d.ts.map +1 -0
- package/dist/Watch.js +46 -0
- package/dist/index.d.ts +56 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -1
- package/dist/internal/budget.d.ts +90 -0
- package/dist/internal/budget.d.ts.map +1 -0
- package/dist/internal/budget.js +70 -0
- package/dist/internal/bytePath.d.ts +2 -0
- package/dist/internal/bytePath.d.ts.map +1 -1
- package/dist/internal/bytePath.js +3 -2
- package/dist/internal/bytes.d.ts +3 -0
- package/dist/internal/bytes.d.ts.map +1 -1
- package/dist/internal/bytes.js +4 -2
- package/dist/internal/canonicalBase64.d.ts +1 -4
- package/dist/internal/canonicalBase64.d.ts.map +1 -1
- package/dist/internal/canonicalBase64.js +9 -13
- package/dist/internal/errors.d.ts +47 -5
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +80 -36
- package/dist/internal/fixture.d.ts +2 -2
- package/dist/internal/fixture.d.ts.map +1 -1
- package/dist/internal/fixture.js +57 -74
- package/dist/internal/hex128.d.ts +12 -0
- package/dist/internal/hex128.d.ts.map +1 -0
- package/dist/internal/hex128.js +7 -0
- package/dist/internal/hmac.d.ts +5 -0
- package/dist/internal/hmac.d.ts.map +1 -0
- package/dist/internal/hmac.js +150 -0
- package/dist/internal/image.d.ts +14 -117
- package/dist/internal/image.d.ts.map +1 -1
- package/dist/internal/image.js +137 -167
- package/dist/internal/inodeTable.d.ts +20 -0
- package/dist/internal/inodeTable.d.ts.map +1 -0
- package/dist/internal/inodeTable.js +48 -0
- package/dist/internal/lines.d.ts +36 -0
- package/dist/internal/lines.d.ts.map +1 -0
- package/dist/internal/lines.js +115 -0
- package/dist/internal/liveImage.d.ts +19 -278
- package/dist/internal/liveImage.d.ts.map +1 -1
- package/dist/internal/liveImage.js +75 -166
- package/dist/internal/merkle.d.ts +45 -0
- package/dist/internal/merkle.d.ts.map +1 -0
- package/dist/internal/merkle.js +179 -0
- package/dist/internal/metadata.d.ts +2 -13
- package/dist/internal/metadata.d.ts.map +1 -1
- package/dist/internal/metadata.js +5 -15
- package/dist/internal/overlayDiff.d.ts +2 -2
- package/dist/internal/overlayDiff.d.ts.map +1 -1
- package/dist/internal/overlayDiff.js +4 -15
- package/dist/internal/path.d.ts +17 -5
- package/dist/internal/path.d.ts.map +1 -1
- package/dist/internal/path.js +38 -24
- package/dist/internal/snapshotDelta.d.ts +61 -60
- package/dist/internal/snapshotDelta.d.ts.map +1 -1
- package/dist/internal/snapshotDelta.js +605 -503
- package/dist/internal/snapshotDeltaModel.d.ts.map +1 -1
- package/dist/internal/snapshotDeltaModel.js +0 -1
- package/dist/internal/testSeams.d.ts +17 -0
- package/dist/internal/testSeams.d.ts.map +1 -0
- package/dist/internal/testSeams.js +20 -0
- package/dist/internal/tree.d.ts +225 -0
- package/dist/internal/tree.d.ts.map +1 -0
- package/dist/internal/tree.js +385 -0
- package/dist/internal/turnstile.d.ts +8 -0
- package/dist/internal/turnstile.d.ts.map +1 -0
- package/dist/internal/turnstile.js +43 -0
- package/dist/internal/virtualFileSystem.d.ts +44 -488
- package/dist/internal/virtualFileSystem.d.ts.map +1 -1
- package/dist/internal/virtualFileSystem.js +2111 -2466
- package/dist/internal/volumeState.d.ts +111 -0
- package/dist/internal/volumeState.d.ts.map +1 -0
- package/dist/internal/volumeState.js +202 -0
- package/dist/internal/watchHub.d.ts +15 -6
- package/dist/internal/watchHub.d.ts.map +1 -1
- package/dist/internal/watchHub.js +56 -42
- package/package.json +54 -10
- package/dist/VirtualFileSystemError.d.ts +0 -54
- package/dist/VirtualFileSystemError.d.ts.map +0 -1
- package/dist/VirtualFileSystemError.js +0 -49
- package/dist/internal/overlayContent.d.ts +0 -15
- package/dist/internal/overlayContent.d.ts.map +0 -1
- package/dist/internal/overlayContent.js +0 -29
- package/dist/internal/stagedState.d.ts +0 -22
- package/dist/internal/stagedState.d.ts.map +0 -1
- package/dist/internal/stagedState.js +0 -62
- package/dist/internal/testHooks.d.ts +0 -20
- package/dist/internal/testHooks.d.ts.map +0 -1
- package/dist/internal/testHooks.js +0 -23
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as Brand from "effect/Brand";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Order from "effect/Order";
|
|
4
|
+
import type { Metadata } from "../Metadata.js";
|
|
5
|
+
import * as InodeTable from "./inodeTable.js";
|
|
6
|
+
import type { StoredMetadata } from "./metadata.js";
|
|
7
|
+
/** @internal */
|
|
8
|
+
export type Ino = number & Brand.Brand<"@effect-vfs/core/Ino">;
|
|
9
|
+
/** @internal */
|
|
10
|
+
export declare const Ino: Brand.Constructor<Ino>;
|
|
11
|
+
/** @internal */
|
|
12
|
+
export declare const ROOT_INO: Ino;
|
|
13
|
+
/** @internal */
|
|
14
|
+
export declare const MAX_INO: number;
|
|
15
|
+
/** @internal */
|
|
16
|
+
export declare const MAX_FILE_BYTES = 4294967295;
|
|
17
|
+
/** @internal */
|
|
18
|
+
export declare const WALK_YIELD_INTERVAL = 128;
|
|
19
|
+
/** @internal */
|
|
20
|
+
export interface Link {
|
|
21
|
+
readonly parent: Ino;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
}
|
|
24
|
+
/** @internal */
|
|
25
|
+
export type NodeMetadata = Omit<Metadata, "revision">;
|
|
26
|
+
/** @internal */
|
|
27
|
+
export interface Directory {
|
|
28
|
+
readonly kind: "directory";
|
|
29
|
+
readonly ino: Ino;
|
|
30
|
+
readonly parent: Ino;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly entries: ReadonlyMap<string, Ino>;
|
|
33
|
+
readonly metadata: NodeMetadata;
|
|
34
|
+
readonly revision: bigint;
|
|
35
|
+
}
|
|
36
|
+
/** @internal */
|
|
37
|
+
export interface RegularFile {
|
|
38
|
+
readonly kind: "file";
|
|
39
|
+
readonly ino: Ino;
|
|
40
|
+
readonly data: Uint8Array;
|
|
41
|
+
readonly links: ReadonlyArray<Link>;
|
|
42
|
+
readonly metadata: NodeMetadata;
|
|
43
|
+
readonly revision: bigint;
|
|
44
|
+
}
|
|
45
|
+
/** @internal */
|
|
46
|
+
export interface SymbolicLink {
|
|
47
|
+
readonly kind: "symlink";
|
|
48
|
+
readonly ino: Ino;
|
|
49
|
+
readonly target: Uint8Array;
|
|
50
|
+
readonly links: ReadonlyArray<Link>;
|
|
51
|
+
readonly metadata: NodeMetadata;
|
|
52
|
+
readonly revision: bigint;
|
|
53
|
+
}
|
|
54
|
+
/** @internal */
|
|
55
|
+
export type Node = Directory | RegularFile | SymbolicLink;
|
|
56
|
+
/** @internal */
|
|
57
|
+
export interface VolumeState {
|
|
58
|
+
readonly inodes: InodeTable.InodeTable<Node>;
|
|
59
|
+
readonly open: ReadonlyMap<Ino, number>;
|
|
60
|
+
readonly nextInode: Ino;
|
|
61
|
+
readonly revision: bigint;
|
|
62
|
+
readonly entries: number;
|
|
63
|
+
readonly usedBytes: bigint;
|
|
64
|
+
}
|
|
65
|
+
/** @internal */
|
|
66
|
+
export declare const getNode: (state: VolumeState, ino: Ino) => Node | undefined;
|
|
67
|
+
/** @internal */
|
|
68
|
+
export declare const byIno: Order.Order<Node>;
|
|
69
|
+
/** @internal */
|
|
70
|
+
export declare const byEntryName: Order.Order<readonly [string, Ino]>;
|
|
71
|
+
/** @internal */
|
|
72
|
+
export declare const payloadOf: (node: Node) => Uint8Array | undefined;
|
|
73
|
+
/** @internal */
|
|
74
|
+
export declare const directoryMetadata: (ino: bigint, uid: number, gid: number, mode: number, now: bigint) => NodeMetadata;
|
|
75
|
+
/** @internal */
|
|
76
|
+
export declare const emptyRoot: (now: bigint) => Directory;
|
|
77
|
+
/** @internal */
|
|
78
|
+
export declare const storedMetadata: (metadata: NodeMetadata) => StoredMetadata;
|
|
79
|
+
/** @internal */
|
|
80
|
+
export declare const reachableNodes: (state: VolumeState) => Effect.Effect<Node[], never, never>;
|
|
81
|
+
/** @internal */
|
|
82
|
+
export declare const reachableValue: (source: VolumeState) => Effect.Effect<{
|
|
83
|
+
state: VolumeState;
|
|
84
|
+
largestFile: number;
|
|
85
|
+
}, never, never>;
|
|
86
|
+
/** @internal */
|
|
87
|
+
export type NodeSpec = {
|
|
88
|
+
readonly kind: "directory";
|
|
89
|
+
readonly ino: Ino;
|
|
90
|
+
readonly parent: Ino;
|
|
91
|
+
readonly name: string;
|
|
92
|
+
readonly metadata: StoredMetadata;
|
|
93
|
+
readonly revision: bigint;
|
|
94
|
+
} | {
|
|
95
|
+
readonly kind: "file";
|
|
96
|
+
readonly ino: Ino;
|
|
97
|
+
readonly links: ReadonlyArray<Link>;
|
|
98
|
+
readonly data: Uint8Array;
|
|
99
|
+
readonly metadata: StoredMetadata;
|
|
100
|
+
readonly revision: bigint;
|
|
101
|
+
} | {
|
|
102
|
+
readonly kind: "symlink";
|
|
103
|
+
readonly ino: Ino;
|
|
104
|
+
readonly links: ReadonlyArray<Link>;
|
|
105
|
+
readonly target: Uint8Array;
|
|
106
|
+
readonly metadata: StoredMetadata;
|
|
107
|
+
readonly revision: bigint;
|
|
108
|
+
};
|
|
109
|
+
/** @internal */
|
|
110
|
+
export declare const assemble: (specs: ReadonlyArray<NodeSpec>) => VolumeState;
|
|
111
|
+
//# sourceMappingURL=volumeState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"volumeState.d.ts","sourceRoot":"","sources":["../../src/internal/volumeState.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import * as Brand from "effect/Brand";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
import * as Match from "effect/Match";
|
|
4
|
+
import * as Order from "effect/Order";
|
|
5
|
+
import * as InodeTable from "./inodeTable.js";
|
|
6
|
+
/** @internal */
|
|
7
|
+
export const Ino = Brand.nominal();
|
|
8
|
+
/** @internal */
|
|
9
|
+
export const ROOT_INO = Ino(1);
|
|
10
|
+
// The largest inode number a value holds. The allocator resumes one above it and must stay exactly representable,
|
|
11
|
+
// since the inode table is keyed by a number.
|
|
12
|
+
/** @internal */
|
|
13
|
+
export const MAX_INO = Number.MAX_SAFE_INTEGER - 1;
|
|
14
|
+
// File sizes fit an unsigned 32-bit count in the volume and its public options.
|
|
15
|
+
/** @internal */
|
|
16
|
+
export const MAX_FILE_BYTES = 0xffffffff;
|
|
17
|
+
// Nodes walked between yields. Whole-tree reads are one synchronous tick otherwise, which
|
|
18
|
+
// starves the event loop and leaves nothing for interruption to act on.
|
|
19
|
+
/** @internal */
|
|
20
|
+
export const WALK_YIELD_INTERVAL = 128;
|
|
21
|
+
/** @internal */
|
|
22
|
+
export const getNode = (state, ino) => InodeTable.get(state.inodes, ino);
|
|
23
|
+
/** @internal */
|
|
24
|
+
export const byIno = Order.mapInput(Order.Number, (node) => node.ino);
|
|
25
|
+
/** @internal */
|
|
26
|
+
export const byEntryName = Order.mapInput(Order.String, ([name]) => name);
|
|
27
|
+
const inNameOrder = (entries) => {
|
|
28
|
+
let previous;
|
|
29
|
+
for (const name of entries.keys()) {
|
|
30
|
+
if (previous !== undefined && previous > name)
|
|
31
|
+
return false;
|
|
32
|
+
previous = name;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
};
|
|
36
|
+
const inEntryOrder = (directory) => inNameOrder(directory.entries)
|
|
37
|
+
? directory
|
|
38
|
+
: { ...directory, entries: new Map([...directory.entries].sort(byEntryName)) };
|
|
39
|
+
/** @internal */
|
|
40
|
+
export const payloadOf = (node) => node.kind === "file" ? node.data : node.kind === "symlink" ? node.target : undefined;
|
|
41
|
+
/** @internal */
|
|
42
|
+
export const directoryMetadata = (ino, uid, gid, mode, now) => ({
|
|
43
|
+
kind: "directory",
|
|
44
|
+
ino,
|
|
45
|
+
uid,
|
|
46
|
+
gid,
|
|
47
|
+
mode,
|
|
48
|
+
nlink: 2,
|
|
49
|
+
size: 0n,
|
|
50
|
+
atimeNs: now,
|
|
51
|
+
mtimeNs: now,
|
|
52
|
+
ctimeNs: now,
|
|
53
|
+
birthtimeNs: now
|
|
54
|
+
});
|
|
55
|
+
/** @internal */
|
|
56
|
+
export const emptyRoot = (now) => ({
|
|
57
|
+
kind: "directory",
|
|
58
|
+
ino: ROOT_INO,
|
|
59
|
+
parent: ROOT_INO,
|
|
60
|
+
name: "",
|
|
61
|
+
entries: new Map(),
|
|
62
|
+
metadata: directoryMetadata(BigInt(ROOT_INO), 0, 0, 0o755, now),
|
|
63
|
+
revision: 1n
|
|
64
|
+
});
|
|
65
|
+
/** @internal */
|
|
66
|
+
export const storedMetadata = (metadata) => ({
|
|
67
|
+
uid: metadata.uid,
|
|
68
|
+
gid: metadata.gid,
|
|
69
|
+
mode: metadata.mode,
|
|
70
|
+
atimeNs: metadata.atimeNs,
|
|
71
|
+
mtimeNs: metadata.mtimeNs,
|
|
72
|
+
ctimeNs: metadata.ctimeNs,
|
|
73
|
+
birthtimeNs: metadata.birthtimeNs
|
|
74
|
+
});
|
|
75
|
+
/** @internal */
|
|
76
|
+
export const reachableNodes = Effect.fnUntraced(function* (state) {
|
|
77
|
+
const nodes = [];
|
|
78
|
+
const seen = new Set([ROOT_INO]);
|
|
79
|
+
const pending = [ROOT_INO];
|
|
80
|
+
for (let index = 0; index < pending.length; index++) {
|
|
81
|
+
if (index % WALK_YIELD_INTERVAL === 0)
|
|
82
|
+
yield* Effect.yieldNow;
|
|
83
|
+
const ino = pending[index];
|
|
84
|
+
const node = ino === undefined ? undefined : getNode(state, ino);
|
|
85
|
+
if (node === undefined)
|
|
86
|
+
continue;
|
|
87
|
+
nodes.push(node);
|
|
88
|
+
if (node.kind !== "directory")
|
|
89
|
+
continue;
|
|
90
|
+
for (const child of node.entries.values()) {
|
|
91
|
+
if (seen.has(child))
|
|
92
|
+
continue;
|
|
93
|
+
seen.add(child);
|
|
94
|
+
pending.push(child);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return nodes;
|
|
98
|
+
});
|
|
99
|
+
const atFirstRevision = (node) => node.revision === 1n ? node : { ...node, revision: 1n };
|
|
100
|
+
// A value holding only what a name reaches, and the size of its largest file. A captured value keeps unlinked
|
|
101
|
+
// open files and detached directories a handle holds; a volume started from it has neither handle, so it starts
|
|
102
|
+
// without them. Each directory lists its entries in the byte order of their names, as a decoded tree's do, so a
|
|
103
|
+
// volume lists the same whether it was restored from a snapshot or from that snapshot's bytes. Its revisions start
|
|
104
|
+
// afresh at the first one, as a decoded tree's do, since a snapshot holds none. Every payload stays shared with the
|
|
105
|
+
// source; only a node whose revision is not the first, or a directory whose entries were in another order, is copied.
|
|
106
|
+
/** @internal */
|
|
107
|
+
export const reachableValue = Effect.fnUntraced(function* (source) {
|
|
108
|
+
const nodes = yield* reachableNodes(source);
|
|
109
|
+
const owner = Symbol();
|
|
110
|
+
let inodes = InodeTable.empty();
|
|
111
|
+
let entries = 0;
|
|
112
|
+
let usedBytes = 0n;
|
|
113
|
+
let largestFile = 0;
|
|
114
|
+
for (const node of nodes) {
|
|
115
|
+
inodes = InodeTable.set(inodes, node.ino, atFirstRevision(node.kind === "directory" ? inEntryOrder(node) : node), owner);
|
|
116
|
+
if (node.kind === "directory")
|
|
117
|
+
entries += node.entries.size;
|
|
118
|
+
else if (node.kind === "symlink")
|
|
119
|
+
usedBytes += BigInt(node.target.length);
|
|
120
|
+
else {
|
|
121
|
+
usedBytes += BigInt(node.data.length);
|
|
122
|
+
largestFile = Math.max(largestFile, node.data.length);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const state = {
|
|
126
|
+
inodes,
|
|
127
|
+
open: new Map(),
|
|
128
|
+
nextInode: source.nextInode,
|
|
129
|
+
revision: 1n,
|
|
130
|
+
entries,
|
|
131
|
+
usedBytes
|
|
132
|
+
};
|
|
133
|
+
return { state, largestFile };
|
|
134
|
+
});
|
|
135
|
+
// Builds the value a set of nodes describes. The caller has checked that the nodes form a tree under the root:
|
|
136
|
+
// every parent is a directory among them, no directory holds a name twice, and every directory reaches the root.
|
|
137
|
+
// Each directory lists its entries in the byte order of their names, so the value does not depend on the order
|
|
138
|
+
// the nodes arrive in. Link counts and sizes come from the nodes, and the allocator resumes past the largest inode.
|
|
139
|
+
/** @internal */
|
|
140
|
+
export const assemble = (specs) => {
|
|
141
|
+
const edges = new Map();
|
|
142
|
+
const subdirectories = new Map();
|
|
143
|
+
let entries = 0;
|
|
144
|
+
let usedBytes = 0n;
|
|
145
|
+
let nextInode = Ino(ROOT_INO + 1);
|
|
146
|
+
let revision = 1n;
|
|
147
|
+
const attach = (parent, name, child) => {
|
|
148
|
+
const listed = edges.get(parent);
|
|
149
|
+
if (listed === undefined)
|
|
150
|
+
edges.set(parent, [[name, child]]);
|
|
151
|
+
else
|
|
152
|
+
listed.push([name, child]);
|
|
153
|
+
entries++;
|
|
154
|
+
};
|
|
155
|
+
for (const spec of specs) {
|
|
156
|
+
if (spec.ino >= nextInode)
|
|
157
|
+
nextInode = Ino(spec.ino + 1);
|
|
158
|
+
if (spec.revision > revision)
|
|
159
|
+
revision = spec.revision;
|
|
160
|
+
if (spec.kind === "directory") {
|
|
161
|
+
if (spec.ino === ROOT_INO)
|
|
162
|
+
continue;
|
|
163
|
+
attach(spec.parent, spec.name, spec.ino);
|
|
164
|
+
subdirectories.set(spec.parent, (subdirectories.get(spec.parent) ?? 0) + 1);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
usedBytes += BigInt(spec.kind === "file" ? spec.data.length : spec.target.length);
|
|
168
|
+
for (const link of spec.links)
|
|
169
|
+
attach(link.parent, link.name, spec.ino);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
const owner = Symbol();
|
|
173
|
+
let inodes = InodeTable.empty();
|
|
174
|
+
for (const spec of specs) {
|
|
175
|
+
const base = { ...spec.metadata, ino: BigInt(spec.ino) };
|
|
176
|
+
const node = Match.value(spec).pipe(Match.discriminator("kind")("directory", (directory) => ({
|
|
177
|
+
kind: "directory",
|
|
178
|
+
ino: directory.ino,
|
|
179
|
+
parent: directory.parent,
|
|
180
|
+
name: directory.name,
|
|
181
|
+
entries: new Map((edges.get(directory.ino) ?? []).sort(byEntryName)),
|
|
182
|
+
metadata: { ...base, kind: "directory", nlink: 2 + (subdirectories.get(directory.ino) ?? 0), size: 0n },
|
|
183
|
+
revision: directory.revision
|
|
184
|
+
})), Match.discriminator("kind")("file", (file) => ({
|
|
185
|
+
kind: "file",
|
|
186
|
+
ino: file.ino,
|
|
187
|
+
data: file.data,
|
|
188
|
+
links: file.links,
|
|
189
|
+
metadata: { ...base, kind: "file", nlink: file.links.length, size: BigInt(file.data.length) },
|
|
190
|
+
revision: file.revision
|
|
191
|
+
})), Match.discriminator("kind")("symlink", (symlink) => ({
|
|
192
|
+
kind: "symlink",
|
|
193
|
+
ino: symlink.ino,
|
|
194
|
+
target: symlink.target,
|
|
195
|
+
links: symlink.links,
|
|
196
|
+
metadata: { ...base, kind: "symlink", nlink: symlink.links.length, size: BigInt(symlink.target.length) },
|
|
197
|
+
revision: symlink.revision
|
|
198
|
+
})), Match.exhaustive);
|
|
199
|
+
inodes = InodeTable.set(inodes, spec.ino, node, owner);
|
|
200
|
+
}
|
|
201
|
+
return { inodes, open: new Map(), nextInode, revision, entries, usedBytes };
|
|
202
|
+
};
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import * as Effect from "effect/Effect";
|
|
2
|
-
import
|
|
2
|
+
import * as Scope from "effect/Scope";
|
|
3
3
|
import * as Stream from "effect/Stream";
|
|
4
4
|
/** @internal */
|
|
5
5
|
export interface Coordinator {
|
|
6
6
|
<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, R>;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Selection callbacks share the context of their publication.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export interface Selection<A, C> {
|
|
14
|
+
readonly includes: (event: A, context: C) => boolean;
|
|
15
|
+
readonly rescan: (context: C) => A;
|
|
16
|
+
readonly settle?: (context: C) => Iterable<A> | undefined;
|
|
17
|
+
}
|
|
8
18
|
/** @internal */
|
|
9
|
-
export interface WatchHub<A, E = never> {
|
|
10
|
-
readonly publishUnsafe: (
|
|
11
|
-
readonly
|
|
12
|
-
readonly subscribe: (afterSubscribe?: Effect.Effect<void>) => Effect.Effect<Stream.Stream<A>, E, Scope.Scope>;
|
|
19
|
+
export interface WatchHub<A, C, E = never> {
|
|
20
|
+
readonly publishUnsafe: (events: () => Iterable<A>, context: C) => void;
|
|
21
|
+
readonly subscribe: (select: Effect.Effect<Selection<A, C>, E>, afterSubscribe: Effect.Effect<void>) => Effect.Effect<Stream.Stream<A>, E, Scope.Scope>;
|
|
13
22
|
}
|
|
14
23
|
/** @internal */
|
|
15
|
-
export declare const make: <A, E = never>(coordinate: Coordinator, capacity: number
|
|
24
|
+
export declare const make: <A, C, E = never>(coordinate: Coordinator, capacity: number) => Effect.Effect<WatchHub<A, C, E>, never, never>;
|
|
16
25
|
//# sourceMappingURL=watchHub.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watchHub.d.ts","sourceRoot":"","sources":["../../src/internal/watchHub.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"watchHub.d.ts","sourceRoot":"","sources":["../../src/internal/watchHub.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,gBAAgB;AAChB,MAAM,WAAW,WAAW;IAC1B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;CAClE;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC,EAAE,CAAC;IAE7B,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,OAAO,CAAA;IACpD,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAA;IAElC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;CAC1D;AAED,gBAAgB;AAChB,MAAM,WAAW,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK;IACvC,QAAQ,CAAC,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,IAAI,CAAA;IACvE,QAAQ,CAAC,SAAS,EAAE,CAClB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EACzC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAChC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;CACrD;AAQD,gBAAgB;AAChB,eAAO,MAAM,IAAI,GAA+B,CAAC,EAAE,CAAC,EAAE,CAAC,sGAwFrD,CAAA"}
|
|
@@ -1,54 +1,68 @@
|
|
|
1
1
|
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Predicate from "effect/Predicate";
|
|
2
3
|
import * as Queue from "effect/Queue";
|
|
4
|
+
import * as Scope from "effect/Scope";
|
|
3
5
|
import * as Stream from "effect/Stream";
|
|
4
6
|
/** @internal */
|
|
5
|
-
export const make = Effect.fnUntraced(function* (coordinate, capacity
|
|
7
|
+
export const make = Effect.fnUntraced(function* (coordinate, capacity) {
|
|
6
8
|
const subscribers = new Set();
|
|
7
|
-
const
|
|
9
|
+
const offer = (subscriber, event, context) => {
|
|
10
|
+
const size = Queue.sizeUnsafe(subscriber.queue);
|
|
11
|
+
// An empty queue means the consumer has taken the rescan marker.
|
|
12
|
+
if (subscriber.overflowed && size > 0)
|
|
13
|
+
return;
|
|
14
|
+
subscriber.overflowed = size >= capacity - 1;
|
|
15
|
+
Queue.offerUnsafe(subscriber.queue, subscriber.overflowed ? subscriber.selection.rescan(context) : event);
|
|
16
|
+
};
|
|
17
|
+
const publishUnsafe = (events, context) => {
|
|
18
|
+
if (subscribers.size === 0)
|
|
19
|
+
return;
|
|
20
|
+
for (const event of events()) {
|
|
21
|
+
for (const subscriber of subscribers) {
|
|
22
|
+
if (subscriber.selection.includes(event, context))
|
|
23
|
+
offer(subscriber, event, context);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
8
26
|
for (const subscriber of subscribers) {
|
|
9
|
-
|
|
27
|
+
const last = subscriber.selection.settle?.(context);
|
|
28
|
+
if (last === undefined)
|
|
10
29
|
continue;
|
|
11
|
-
|
|
30
|
+
for (const event of last)
|
|
12
31
|
Queue.offerUnsafe(subscriber.queue, event);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
subscriber.overflowed = true;
|
|
16
|
-
subscriber.marker = rescan();
|
|
17
|
-
Queue.offerUnsafe(subscriber.queue, subscriber.marker);
|
|
18
|
-
}
|
|
32
|
+
subscribers.delete(subscriber);
|
|
33
|
+
Queue.endUnsafe(subscriber.queue);
|
|
19
34
|
}
|
|
20
35
|
};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
yield*
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (afterSubscribe !== undefined)
|
|
36
|
+
// Register cleanup before waiting for the volume, including when the scope closes during registration.
|
|
37
|
+
const subscribe = Effect.fnUntraced(function* (select, afterSubscribe) {
|
|
38
|
+
const scope = yield* Effect.scope;
|
|
39
|
+
let registered;
|
|
40
|
+
yield* Scope.addFinalizer(scope, Effect.suspend(() => {
|
|
41
|
+
const subscriber = registered;
|
|
42
|
+
if (subscriber === undefined)
|
|
43
|
+
return Effect.void;
|
|
44
|
+
return coordinate(Effect.sync(() => subscribers.delete(subscriber))).pipe(Effect.andThen(Queue.shutdown(subscriber.queue)));
|
|
45
|
+
}));
|
|
46
|
+
const closed = () => Predicate.isTagged(scope.state, "Closed");
|
|
47
|
+
const subscriber = yield* coordinate(Effect.gen(function* () {
|
|
48
|
+
const selection = yield* select;
|
|
49
|
+
const created = {
|
|
50
|
+
// Reserve one slot for a final event behind a rescan marker.
|
|
51
|
+
queue: yield* Queue.bounded(capacity + 1),
|
|
52
|
+
selection,
|
|
53
|
+
overflowed: false
|
|
54
|
+
};
|
|
41
55
|
yield* afterSubscribe;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
return
|
|
52
|
-
})
|
|
53
|
-
return { publishUnsafe,
|
|
56
|
+
// Cleanup may have run before registration; discard the subscriber if the scope closed.
|
|
57
|
+
if (closed()) {
|
|
58
|
+
yield* Queue.shutdown(created.queue);
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
subscribers.add(created);
|
|
62
|
+
registered = created;
|
|
63
|
+
return created;
|
|
64
|
+
}));
|
|
65
|
+
return subscriber === undefined ? Stream.empty : Stream.fromEffectRepeat(Queue.take(subscriber.queue));
|
|
66
|
+
});
|
|
67
|
+
return { publishUnsafe, subscribe };
|
|
54
68
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect-vfs/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "A runtime-neutral virtual filesystem core for Effect.",
|
|
5
5
|
"homepage": "https://github.com/lloydrichards/effect-virtual-fs#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -21,18 +21,18 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "tsc --project tsconfig.build.json && tsc --project compatibility/node-next/tsconfig.json",
|
|
23
23
|
"clean": "git clean -xdf .cache .turbo dist docs node_modules tsconfig.tsbuildinfo",
|
|
24
|
-
"test": "vitest run",
|
|
24
|
+
"test": "bun --bun run vitest run --config ../../vitest.config.ts --project core",
|
|
25
25
|
"type-check": "tsc --noEmit && tsc --project contracts/tsconfig.json"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"effect": "4.0.0-rc.
|
|
28
|
+
"effect": "4.0.0-rc.117"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@effect/platform-bun": "4.0.0-rc.
|
|
32
|
-
"@effect/platform-node-shared": "4.0.0-rc.
|
|
33
|
-
"@effect/vitest": "4.0.0-rc.
|
|
31
|
+
"@effect/platform-bun": "4.0.0-rc.117",
|
|
32
|
+
"@effect/platform-node-shared": "4.0.0-rc.117",
|
|
33
|
+
"@effect/vitest": "4.0.0-rc.117",
|
|
34
34
|
"@repo/config-typescript": "workspace:*",
|
|
35
|
-
"effect": "4.0.0-rc.
|
|
35
|
+
"effect": "4.0.0-rc.117"
|
|
36
36
|
},
|
|
37
37
|
"exports": {
|
|
38
38
|
".": {
|
|
@@ -43,14 +43,58 @@
|
|
|
43
43
|
"types": "./dist/VirtualFileSystem.d.ts",
|
|
44
44
|
"import": "./dist/VirtualFileSystem.js"
|
|
45
45
|
},
|
|
46
|
-
"./
|
|
47
|
-
"types": "./dist/
|
|
48
|
-
"import": "./dist/
|
|
46
|
+
"./VfsError": {
|
|
47
|
+
"types": "./dist/VfsError.d.ts",
|
|
48
|
+
"import": "./dist/VfsError.js"
|
|
49
49
|
},
|
|
50
50
|
"./LiveVolume": {
|
|
51
51
|
"types": "./dist/LiveVolume.d.ts",
|
|
52
52
|
"import": "./dist/LiveVolume.js"
|
|
53
53
|
},
|
|
54
|
+
"./Caller": {
|
|
55
|
+
"types": "./dist/Caller.d.ts",
|
|
56
|
+
"import": "./dist/Caller.js"
|
|
57
|
+
},
|
|
58
|
+
"./FileHandle": {
|
|
59
|
+
"types": "./dist/FileHandle.d.ts",
|
|
60
|
+
"import": "./dist/FileHandle.js"
|
|
61
|
+
},
|
|
62
|
+
"./Fixture": {
|
|
63
|
+
"types": "./dist/Fixture.d.ts",
|
|
64
|
+
"import": "./dist/Fixture.js"
|
|
65
|
+
},
|
|
66
|
+
"./Metadata": {
|
|
67
|
+
"types": "./dist/Metadata.d.ts",
|
|
68
|
+
"import": "./dist/Metadata.js"
|
|
69
|
+
},
|
|
70
|
+
"./Target": {
|
|
71
|
+
"types": "./dist/Target.d.ts",
|
|
72
|
+
"import": "./dist/Target.js"
|
|
73
|
+
},
|
|
74
|
+
"./Volume": {
|
|
75
|
+
"types": "./dist/Volume.d.ts",
|
|
76
|
+
"import": "./dist/Volume.js"
|
|
77
|
+
},
|
|
78
|
+
"./Watch": {
|
|
79
|
+
"types": "./dist/Watch.d.ts",
|
|
80
|
+
"import": "./dist/Watch.js"
|
|
81
|
+
},
|
|
82
|
+
"./BytePath": {
|
|
83
|
+
"types": "./dist/BytePath.d.ts",
|
|
84
|
+
"import": "./dist/BytePath.js"
|
|
85
|
+
},
|
|
86
|
+
"./Snapshot": {
|
|
87
|
+
"types": "./dist/Snapshot.d.ts",
|
|
88
|
+
"import": "./dist/Snapshot.js"
|
|
89
|
+
},
|
|
90
|
+
"./SnapshotDelta": {
|
|
91
|
+
"types": "./dist/SnapshotDelta.d.ts",
|
|
92
|
+
"import": "./dist/SnapshotDelta.js"
|
|
93
|
+
},
|
|
94
|
+
"./Testing": {
|
|
95
|
+
"types": "./dist/Testing.d.ts",
|
|
96
|
+
"import": "./dist/Testing.js"
|
|
97
|
+
},
|
|
54
98
|
"./internal/*": null,
|
|
55
99
|
"./index": null,
|
|
56
100
|
"./*/index": null,
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type { FsCode, PathInput } from "./VirtualFileSystem.js";
|
|
2
|
-
declare const FsError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
3
|
-
readonly _tag: "FsError";
|
|
4
|
-
} & Readonly<A>;
|
|
5
|
-
/**
|
|
6
|
-
* An expected filesystem operation failure.
|
|
7
|
-
*
|
|
8
|
-
* The `code` distinguishes portable failures while `operation` names the action.
|
|
9
|
-
* Byte paths are intentionally omitted from the formatted message.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* import { VirtualFileSystemError } from "@effect-vfs/core"
|
|
14
|
-
*
|
|
15
|
-
* const error = new VirtualFileSystemError.FsError({ code: "NotFound", operation: "readFile" })
|
|
16
|
-
* console.log(error.code, error.message)
|
|
17
|
-
* // NotFound readFile failed with NotFound
|
|
18
|
-
* ```
|
|
19
|
-
*
|
|
20
|
-
* @category errors
|
|
21
|
-
* @since 0.1.0
|
|
22
|
-
*/
|
|
23
|
-
export declare class FsError extends FsError_base<{
|
|
24
|
-
readonly code: FsCode;
|
|
25
|
-
readonly operation: string;
|
|
26
|
-
readonly path?: PathInput;
|
|
27
|
-
}> {
|
|
28
|
-
get message(): string;
|
|
29
|
-
}
|
|
30
|
-
declare const ConfigurationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
31
|
-
readonly _tag: "ConfigurationError";
|
|
32
|
-
} & Readonly<A>;
|
|
33
|
-
/**
|
|
34
|
-
* An invalid volume or caller option, identified by its field name.
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```ts
|
|
38
|
-
* import { VirtualFileSystemError } from "@effect-vfs/core"
|
|
39
|
-
*
|
|
40
|
-
* const error = new VirtualFileSystemError.ConfigurationError({ field: "maxEntries" })
|
|
41
|
-
* console.log(error.field, error.message)
|
|
42
|
-
* // maxEntries Invalid option: maxEntries
|
|
43
|
-
* ```
|
|
44
|
-
*
|
|
45
|
-
* @category errors
|
|
46
|
-
* @since 0.1.0
|
|
47
|
-
*/
|
|
48
|
-
export declare class ConfigurationError extends ConfigurationError_base<{
|
|
49
|
-
readonly field: string;
|
|
50
|
-
}> {
|
|
51
|
-
get message(): string;
|
|
52
|
-
}
|
|
53
|
-
export {};
|
|
54
|
-
//# sourceMappingURL=VirtualFileSystemError.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VirtualFileSystemError.d.ts","sourceRoot":"","sources":["../src/VirtualFileSystemError.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;;;;AAE/D;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,OAAQ,SAAQ,aAA4B;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAA;CAC1B,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAE7B;CACF;;;;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAE7B;CACF"}
|