@effect-vfs/core 0.8.0 → 0.10.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 +9 -0
- package/dist/BytePath.d.ts +4 -1
- package/dist/BytePath.d.ts.map +1 -1
- package/dist/BytePath.js +6 -4
- package/dist/Caller.d.ts +107 -66
- package/dist/Caller.d.ts.map +1 -1
- package/dist/Caller.js +16 -86
- package/dist/LiveVolume.d.ts +75 -2
- package/dist/LiveVolume.d.ts.map +1 -1
- package/dist/LiveVolume.js +87 -3
- package/dist/Search.d.ts +32 -8
- package/dist/Search.d.ts.map +1 -1
- package/dist/Search.js +19 -10
- package/dist/SynchronousAdapter.d.ts +58 -0
- package/dist/SynchronousAdapter.d.ts.map +1 -0
- package/dist/SynchronousAdapter.js +116 -0
- package/dist/Target.d.ts +7 -91
- package/dist/Target.d.ts.map +1 -1
- package/dist/Target.js +7 -47
- package/dist/Testing.d.ts +5 -2
- package/dist/Testing.d.ts.map +1 -1
- package/dist/Testing.js +2 -1
- package/dist/VfsError.d.ts +4 -2
- package/dist/VfsError.d.ts.map +1 -1
- package/dist/VfsError.js +3 -1
- package/dist/VirtualFileSystem.d.ts +151 -44
- package/dist/VirtualFileSystem.d.ts.map +1 -1
- package/dist/VirtualFileSystem.js +31 -21
- package/dist/Volume.d.ts +6 -1
- package/dist/Volume.d.ts.map +1 -1
- package/dist/Volume.js +6 -2
- package/dist/Watch.d.ts +18 -0
- package/dist/Watch.d.ts.map +1 -1
- package/dist/Watch.js +12 -0
- package/dist/internal/adapterBinding.d.ts +13 -0
- package/dist/internal/adapterBinding.d.ts.map +1 -0
- package/dist/internal/adapterBinding.js +13 -0
- package/dist/internal/bytePath.d.ts +6 -1
- package/dist/internal/bytePath.d.ts.map +1 -1
- package/dist/internal/callerWatch.d.ts +36 -0
- package/dist/internal/callerWatch.d.ts.map +1 -0
- package/dist/internal/callerWatch.js +185 -0
- package/dist/internal/engine.d.ts +1305 -0
- package/dist/internal/engine.d.ts.map +1 -0
- package/dist/internal/engine.js +3458 -0
- package/dist/internal/errors.d.ts +1 -33
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +1 -45
- package/dist/internal/fixture.d.ts +2 -1
- package/dist/internal/fixture.d.ts.map +1 -1
- package/dist/internal/fixture.js +8 -4
- package/dist/internal/image.d.ts +4 -1
- package/dist/internal/image.d.ts.map +1 -1
- package/dist/internal/image.js +6 -3
- package/dist/internal/lines.d.ts.map +1 -1
- package/dist/internal/lines.js +3 -2
- package/dist/internal/liveImage.d.ts +4 -2
- package/dist/internal/liveImage.d.ts.map +1 -1
- package/dist/internal/liveImage.js +3 -1
- package/dist/internal/merkle.d.ts +7 -4
- package/dist/internal/merkle.d.ts.map +1 -1
- package/dist/internal/merkle.js +6 -4
- package/dist/internal/search.d.ts +3 -1
- package/dist/internal/search.d.ts.map +1 -1
- package/dist/internal/search.js +4 -3
- package/dist/internal/snapshotDelta.d.ts +11 -7
- package/dist/internal/snapshotDelta.d.ts.map +1 -1
- package/dist/internal/snapshotDelta.js +15 -9
- package/dist/internal/snapshotMerge.d.ts +1 -1
- package/dist/internal/snapshotMerge.d.ts.map +1 -1
- package/dist/internal/snapshotMerge.js +5 -2
- package/dist/internal/tree.d.ts +4 -2
- package/dist/internal/tree.d.ts.map +1 -1
- package/dist/internal/tree.js +4 -2
- package/dist/internal/virtualFileSystem.d.ts +20 -49
- package/dist/internal/virtualFileSystem.d.ts.map +1 -1
- package/dist/internal/virtualFileSystem.js +85 -1927
- package/dist/internal/volumeLimits.d.ts +1 -0
- package/dist/internal/volumeLimits.d.ts.map +1 -1
- package/dist/internal/volumeLimits.js +3 -2
- package/dist/internal/volumeState.d.ts +10 -79
- package/dist/internal/volumeState.d.ts.map +1 -1
- package/dist/internal/volumeState.js +9 -79
- package/dist/internal/watchHub.d.ts +9 -5
- package/dist/internal/watchHub.d.ts.map +1 -1
- package/dist/internal/watchHub.js +35 -8
- package/package.json +16 -9
- package/dist/internal/inodeTable.d.ts +0 -20
- package/dist/internal/inodeTable.d.ts.map +0 -1
- package/dist/internal/inodeTable.js +0 -48
- package/dist/internal/path.d.ts +0 -56
- package/dist/internal/path.d.ts.map +0 -1
- package/dist/internal/path.js +0 -141
- package/dist/internal/resolution.d.ts +0 -135
- package/dist/internal/resolution.d.ts.map +0 -1
- package/dist/internal/resolution.js +0 -277
- package/dist/internal/testSeams.d.ts +0 -17
- package/dist/internal/testSeams.d.ts.map +0 -1
- package/dist/internal/testSeams.js +0 -20
- package/dist/internal/tokenRegistry.d.ts +0 -77
- package/dist/internal/tokenRegistry.d.ts.map +0 -1
- package/dist/internal/tokenRegistry.js +0 -128
- package/dist/internal/turnstile.d.ts +0 -8
- package/dist/internal/turnstile.d.ts.map +0 -1
- package/dist/internal/turnstile.js +0 -43
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
import * as Scope from "effect/Scope";
|
|
3
|
-
import type { FsFailure } from "../VfsError.js";
|
|
4
|
-
import type { DirectoryHandle, FileHandle, ObjectReference } from "../VirtualFileSystem.js";
|
|
5
|
-
import type { OpContext } from "./errors.js";
|
|
6
|
-
import type { Ino, Node } from "./volumeState.js";
|
|
7
|
-
/** @internal */
|
|
8
|
-
export type HandleLifecycle = {
|
|
9
|
-
readonly kind: "acquiring";
|
|
10
|
-
} | {
|
|
11
|
-
readonly kind: "open";
|
|
12
|
-
readonly ino: Ino;
|
|
13
|
-
} | {
|
|
14
|
-
readonly kind: "releasedPendingCommit";
|
|
15
|
-
readonly ino: Ino | undefined;
|
|
16
|
-
} | {
|
|
17
|
-
readonly kind: "closed";
|
|
18
|
-
};
|
|
19
|
-
/** @internal */
|
|
20
|
-
export interface HandleReference {
|
|
21
|
-
readonly volume: symbol;
|
|
22
|
-
lifecycle: HandleLifecycle;
|
|
23
|
-
scope: Scope.Closeable | undefined;
|
|
24
|
-
}
|
|
25
|
-
/** @internal */
|
|
26
|
-
export interface FileReference extends HandleReference {
|
|
27
|
-
offset: bigint;
|
|
28
|
-
readonly access: "read" | "write" | "readWrite";
|
|
29
|
-
readonly append: boolean;
|
|
30
|
-
}
|
|
31
|
-
/** @internal */
|
|
32
|
-
export type DirectoryReference = HandleReference;
|
|
33
|
-
/** @internal */
|
|
34
|
-
export type Token = ObjectReference | FileHandle | DirectoryHandle;
|
|
35
|
-
/** @internal */
|
|
36
|
-
export type Resolution = {
|
|
37
|
-
readonly kind: "unknown";
|
|
38
|
-
} | {
|
|
39
|
-
readonly kind: "foreign";
|
|
40
|
-
} | {
|
|
41
|
-
readonly kind: "stale";
|
|
42
|
-
} | {
|
|
43
|
-
readonly kind: "live";
|
|
44
|
-
readonly node: Node;
|
|
45
|
-
};
|
|
46
|
-
/** @internal */
|
|
47
|
-
export declare const inode: (reference: HandleReference) => Ino | undefined;
|
|
48
|
-
/** @internal */
|
|
49
|
-
export declare const isOpen: (reference: HandleReference) => boolean;
|
|
50
|
-
/** @internal */
|
|
51
|
-
export declare const publish: (reference: HandleReference, ino: Ino) => void;
|
|
52
|
-
/** @internal */
|
|
53
|
-
export declare const released: (reference: HandleReference) => void;
|
|
54
|
-
/** @internal */
|
|
55
|
-
export declare const release: <E, R>(reference: HandleReference, releaseInode: (ino: Ino) => Effect.Effect<void, E, R>, afterRelease: (action: () => void) => Effect.Effect<void, never, R>) => Effect.Effect<void, E, R>;
|
|
56
|
-
/** @internal */
|
|
57
|
-
export declare const closeReleasedScope: (reference: HandleReference) => Effect.Effect<void, never, never>;
|
|
58
|
-
/** @internal */
|
|
59
|
-
export declare const finalize: (reference: HandleReference, close: Effect.Effect<unknown, FsFailure>, fallback: Effect.Effect<void>) => Effect.Effect<void, never, never>;
|
|
60
|
-
/** @internal */
|
|
61
|
-
export declare const acquire: <A, E, R, ReleaseR, CoordinateR>(reference: HandleReference, coordinate: (acquire: Effect.Effect<A, E, R | ReleaseR>) => Effect.Effect<A, E | FsFailure, CoordinateR>, acquisition: Effect.Effect<A, E, R>, releaseAcquired: () => Effect.Effect<void, never, ReleaseR>, finalizer: Effect.Effect<void, never, never>) => Effect.Effect<A, E | FsFailure, CoordinateR | Scope.Scope>;
|
|
62
|
-
/** @internal */
|
|
63
|
-
export declare const nodeOrFail: (result: Resolution, addressing: "reference" | "handle", op: OpContext) => Effect.Effect<never, FsFailure, never> | Effect.Effect<Node, never, never>;
|
|
64
|
-
/** @internal */
|
|
65
|
-
export declare const make: (volume: symbol, get: (ino: Ino) => Effect.Effect<Node | undefined>) => {
|
|
66
|
-
resolve: (token: Token, addressing: "reference" | "handle" | "directory") => Effect.Effect<Resolution, never, never>;
|
|
67
|
-
resolveInode: (ino: Ino) => Effect.Effect<Resolution>;
|
|
68
|
-
referenceFor: (ino: Ino) => ObjectReference;
|
|
69
|
-
forget: (ino: Ino) => boolean;
|
|
70
|
-
file: (access: FileReference["access"], append: boolean) => FileReference;
|
|
71
|
-
directory: (ino?: Ino) => DirectoryReference;
|
|
72
|
-
registerFile: (handle: FileHandle, reference: FileReference) => WeakMap<object, FileReference>;
|
|
73
|
-
registerDirectory: (handle: DirectoryHandle, reference: DirectoryReference) => WeakMap<object, HandleReference>;
|
|
74
|
-
};
|
|
75
|
-
/** @internal */
|
|
76
|
-
export type TokenRegistry = ReturnType<typeof make>;
|
|
77
|
-
//# sourceMappingURL=tokenRegistry.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tokenRegistry.d.ts","sourceRoot":"","sources":["../../src/internal/tokenRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
import * as Exit from "effect/Exit";
|
|
3
|
-
import * as Predicate from "effect/Predicate";
|
|
4
|
-
import * as Scope from "effect/Scope";
|
|
5
|
-
import { ObjectReferenceId } from "../Caller.js";
|
|
6
|
-
// Shared across volumes so a genuine token from another registry is distinguishable from a forgery.
|
|
7
|
-
const references = new WeakMap();
|
|
8
|
-
const files = new WeakMap();
|
|
9
|
-
const directories = new WeakMap();
|
|
10
|
-
/** @internal */
|
|
11
|
-
export const inode = (reference) => reference.lifecycle.kind === "open" || reference.lifecycle.kind === "releasedPendingCommit"
|
|
12
|
-
? reference.lifecycle.ino
|
|
13
|
-
: undefined;
|
|
14
|
-
/** @internal */
|
|
15
|
-
export const isOpen = (reference) => reference.lifecycle.kind === "open";
|
|
16
|
-
/** @internal */
|
|
17
|
-
export const publish = (reference, ino) => {
|
|
18
|
-
reference.lifecycle = reference.lifecycle.kind === "releasedPendingCommit" || reference.lifecycle.kind === "closed"
|
|
19
|
-
? { kind: "releasedPendingCommit", ino }
|
|
20
|
-
: { kind: "open", ino };
|
|
21
|
-
};
|
|
22
|
-
/** @internal */
|
|
23
|
-
export const released = (reference) => {
|
|
24
|
-
reference.lifecycle = reference.lifecycle.kind === "acquiring" ||
|
|
25
|
-
(reference.lifecycle.kind === "releasedPendingCommit" && reference.lifecycle.ino === undefined)
|
|
26
|
-
? { kind: "releasedPendingCommit", ino: undefined }
|
|
27
|
-
: { kind: "closed" };
|
|
28
|
-
};
|
|
29
|
-
// A release callback changes the engine's draft; publication may be immediate cleanup or after installation.
|
|
30
|
-
/** @internal */
|
|
31
|
-
export const release = Effect.fnUntraced(function* (reference, releaseInode, afterRelease) {
|
|
32
|
-
const ino = inode(reference);
|
|
33
|
-
yield* afterRelease(() => released(reference));
|
|
34
|
-
if (ino !== undefined)
|
|
35
|
-
yield* releaseInode(ino);
|
|
36
|
-
});
|
|
37
|
-
/** @internal */
|
|
38
|
-
export const closeReleasedScope = (reference) => Effect.suspend(() => isOpen(reference) || reference.scope === undefined ? Effect.void : Scope.close(reference.scope, Exit.void));
|
|
39
|
-
// The inode, rather than the open tag, decides whether a rerun must release a late publication.
|
|
40
|
-
/** @internal */
|
|
41
|
-
export const finalize = (reference, close, fallback) => Effect.uninterruptible(Effect.suspend(() => inode(reference) === undefined
|
|
42
|
-
? Effect.sync(() => released(reference))
|
|
43
|
-
: Effect.ignore(close).pipe(Effect.andThen(Effect.suspend(() => inode(reference) === undefined ? Effect.void : fallback)))));
|
|
44
|
-
// Register before waiting: a closed scope runs its finalizer immediately, and engine permits are not reentrant.
|
|
45
|
-
/** @internal */
|
|
46
|
-
export const acquire = Effect.fnUntraced(function* (reference, coordinate, acquisition, releaseAcquired, finalizer) {
|
|
47
|
-
const scope = yield* Scope.fork(yield* Effect.scope);
|
|
48
|
-
reference.scope = scope;
|
|
49
|
-
yield* Scope.addFinalizer(scope, finalizer);
|
|
50
|
-
const closed = () => Predicate.isTagged(scope.state, "Closed");
|
|
51
|
-
return yield* coordinate(Effect.suspend(() => closed() ? Effect.interrupt : acquisition).pipe(Effect.tap(() => Effect.suspend(() => closed() ? Effect.andThen(releaseAcquired(), Effect.interrupt) : Effect.void)))).pipe(Effect.tap(() => Effect.suspend(() => closed() ? Effect.interrupt : Effect.void)), Effect.onError(() => Effect.andThen(finalizer, Scope.close(scope, Exit.void))), Effect.onError(() => Effect.sync(() => {
|
|
52
|
-
if (reference.lifecycle.kind === "releasedPendingCommit" && reference.lifecycle.ino === undefined) {
|
|
53
|
-
reference.lifecycle = { kind: "closed" };
|
|
54
|
-
}
|
|
55
|
-
})));
|
|
56
|
-
});
|
|
57
|
-
/** @internal */
|
|
58
|
-
export const nodeOrFail = (result, addressing, op) => {
|
|
59
|
-
switch (result.kind) {
|
|
60
|
-
case "live":
|
|
61
|
-
return Effect.succeed(result.node);
|
|
62
|
-
case "unknown":
|
|
63
|
-
return Effect.fail(op.fail(addressing === "reference" ? "InvalidReference" : "InvalidHandle"));
|
|
64
|
-
case "foreign":
|
|
65
|
-
return Effect.fail(op.fail(addressing === "reference" ? "ForeignReference" : "ForeignHandle"));
|
|
66
|
-
case "stale":
|
|
67
|
-
return Effect.fail(op.fail(addressing === "reference" ? "StaleReference" : "InvalidHandle"));
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
/** @internal */
|
|
71
|
-
export const make = (volume, get) => {
|
|
72
|
-
const tokens = new Map();
|
|
73
|
-
const resolveInode = (ino) => Effect.map(get(ino), (node) => node === undefined || (node.kind === "directory" && node.metadata.nlink === 0)
|
|
74
|
-
? { kind: "stale" }
|
|
75
|
-
: { kind: "live", node });
|
|
76
|
-
const resolveReference = (token) => Effect.suspend(() => {
|
|
77
|
-
const known = Predicate.isObject(token) ? references.get(token) : undefined;
|
|
78
|
-
if (known === undefined)
|
|
79
|
-
return Effect.succeed({ kind: "unknown" });
|
|
80
|
-
if (known.volume !== volume)
|
|
81
|
-
return Effect.succeed({ kind: "foreign" });
|
|
82
|
-
return resolveInode(known.ino);
|
|
83
|
-
});
|
|
84
|
-
const resolveHandle = (token, directoryOnly = false) => Effect.suspend(() => {
|
|
85
|
-
const known = Predicate.isObject(token)
|
|
86
|
-
? directories.get(token) ?? (directoryOnly ? undefined : files.get(token))
|
|
87
|
-
: undefined;
|
|
88
|
-
if (known === undefined)
|
|
89
|
-
return Effect.succeed({ kind: "unknown" });
|
|
90
|
-
if (known.volume !== volume)
|
|
91
|
-
return Effect.succeed({ kind: "foreign" });
|
|
92
|
-
if (!isOpen(known))
|
|
93
|
-
return Effect.succeed({ kind: "stale" });
|
|
94
|
-
const ino = inode(known);
|
|
95
|
-
return ino === undefined
|
|
96
|
-
? Effect.succeed({ kind: "stale" })
|
|
97
|
-
: Effect.map(get(ino), (node) => node === undefined ? { kind: "stale" } : { kind: "live", node });
|
|
98
|
-
});
|
|
99
|
-
return {
|
|
100
|
-
resolve: (token, addressing) => addressing === "reference" ? resolveReference(token) : resolveHandle(token, addressing === "directory"),
|
|
101
|
-
resolveInode,
|
|
102
|
-
referenceFor: (ino) => {
|
|
103
|
-
const existing = tokens.get(ino);
|
|
104
|
-
if (existing !== undefined)
|
|
105
|
-
return existing;
|
|
106
|
-
const reference = Object.freeze({ [ObjectReferenceId]: true });
|
|
107
|
-
references.set(reference, { volume, ino });
|
|
108
|
-
tokens.set(ino, reference);
|
|
109
|
-
return reference;
|
|
110
|
-
},
|
|
111
|
-
forget: (ino) => tokens.delete(ino),
|
|
112
|
-
file: (access, append) => ({
|
|
113
|
-
volume,
|
|
114
|
-
lifecycle: { kind: "acquiring" },
|
|
115
|
-
scope: undefined,
|
|
116
|
-
offset: 0n,
|
|
117
|
-
access,
|
|
118
|
-
append
|
|
119
|
-
}),
|
|
120
|
-
directory: (ino) => ({
|
|
121
|
-
volume,
|
|
122
|
-
lifecycle: ino === undefined ? { kind: "acquiring" } : { kind: "open", ino },
|
|
123
|
-
scope: undefined
|
|
124
|
-
}),
|
|
125
|
-
registerFile: (handle, reference) => files.set(handle, reference),
|
|
126
|
-
registerDirectory: (handle, reference) => directories.set(handle, reference)
|
|
127
|
-
};
|
|
128
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
/** @internal */
|
|
3
|
-
export interface Turnstile {
|
|
4
|
-
readonly withTurn: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
|
|
5
|
-
}
|
|
6
|
-
/** @internal */
|
|
7
|
-
export declare const makeTurnstile: () => Turnstile;
|
|
8
|
-
//# sourceMappingURL=turnstile.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"turnstile.d.ts","sourceRoot":"","sources":["../../src/internal/turnstile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAIvC,gBAAgB;AAChB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;CACvF;AASD,gBAAgB;AAChB,eAAO,MAAM,aAAa,QAAO,SAkDhC,CAAA"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
import * as Exit from "effect/Exit";
|
|
3
|
-
// A Semaphore can let a newcomer overtake a scheduled waiter. Transfer ownership before scheduling the oldest waiter.
|
|
4
|
-
/** @internal */
|
|
5
|
-
export const makeTurnstile = () => {
|
|
6
|
-
let held = false;
|
|
7
|
-
const waiting = [];
|
|
8
|
-
const release = () => {
|
|
9
|
-
const next = waiting.shift();
|
|
10
|
-
if (next === undefined) {
|
|
11
|
-
held = false;
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
next.granted = true;
|
|
15
|
-
next.dispatcher.scheduleTask(() => next.wake?.(), 0);
|
|
16
|
-
};
|
|
17
|
-
const waitFor = (ticket) => Effect.callback((resume) => {
|
|
18
|
-
if (ticket.granted)
|
|
19
|
-
return resume(Effect.void);
|
|
20
|
-
ticket.wake = () => resume(Effect.void);
|
|
21
|
-
});
|
|
22
|
-
return {
|
|
23
|
-
// Check ticket ownership after interruption so a granted turn is released rather than stranded.
|
|
24
|
-
withTurn: (effect) => Effect.uninterruptibleMask((restore) => Effect.withFiber((fiber) => {
|
|
25
|
-
const run = Effect.ensuring(restore(effect), Effect.sync(release));
|
|
26
|
-
if (!held) {
|
|
27
|
-
held = true;
|
|
28
|
-
return run;
|
|
29
|
-
}
|
|
30
|
-
const ticket = { dispatcher: fiber.currentDispatcher, granted: false, wake: undefined };
|
|
31
|
-
waiting.push(ticket);
|
|
32
|
-
return Effect.flatMap(Effect.exit(restore(waitFor(ticket))), (waited) => {
|
|
33
|
-
if (Exit.isSuccess(waited))
|
|
34
|
-
return run;
|
|
35
|
-
if (ticket.granted)
|
|
36
|
-
release();
|
|
37
|
-
else
|
|
38
|
-
waiting.splice(waiting.indexOf(ticket), 1);
|
|
39
|
-
return Effect.failCause(waited.cause);
|
|
40
|
-
});
|
|
41
|
-
}))
|
|
42
|
-
};
|
|
43
|
-
};
|