@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.
Files changed (105) hide show
  1. package/README.md +9 -0
  2. package/dist/BytePath.d.ts +4 -1
  3. package/dist/BytePath.d.ts.map +1 -1
  4. package/dist/BytePath.js +6 -4
  5. package/dist/Caller.d.ts +107 -66
  6. package/dist/Caller.d.ts.map +1 -1
  7. package/dist/Caller.js +16 -86
  8. package/dist/LiveVolume.d.ts +75 -2
  9. package/dist/LiveVolume.d.ts.map +1 -1
  10. package/dist/LiveVolume.js +87 -3
  11. package/dist/Search.d.ts +32 -8
  12. package/dist/Search.d.ts.map +1 -1
  13. package/dist/Search.js +19 -10
  14. package/dist/SynchronousAdapter.d.ts +58 -0
  15. package/dist/SynchronousAdapter.d.ts.map +1 -0
  16. package/dist/SynchronousAdapter.js +116 -0
  17. package/dist/Target.d.ts +7 -91
  18. package/dist/Target.d.ts.map +1 -1
  19. package/dist/Target.js +7 -47
  20. package/dist/Testing.d.ts +5 -2
  21. package/dist/Testing.d.ts.map +1 -1
  22. package/dist/Testing.js +2 -1
  23. package/dist/VfsError.d.ts +4 -2
  24. package/dist/VfsError.d.ts.map +1 -1
  25. package/dist/VfsError.js +3 -1
  26. package/dist/VirtualFileSystem.d.ts +151 -44
  27. package/dist/VirtualFileSystem.d.ts.map +1 -1
  28. package/dist/VirtualFileSystem.js +31 -21
  29. package/dist/Volume.d.ts +6 -1
  30. package/dist/Volume.d.ts.map +1 -1
  31. package/dist/Volume.js +6 -2
  32. package/dist/Watch.d.ts +18 -0
  33. package/dist/Watch.d.ts.map +1 -1
  34. package/dist/Watch.js +12 -0
  35. package/dist/internal/adapterBinding.d.ts +13 -0
  36. package/dist/internal/adapterBinding.d.ts.map +1 -0
  37. package/dist/internal/adapterBinding.js +13 -0
  38. package/dist/internal/bytePath.d.ts +6 -1
  39. package/dist/internal/bytePath.d.ts.map +1 -1
  40. package/dist/internal/callerWatch.d.ts +36 -0
  41. package/dist/internal/callerWatch.d.ts.map +1 -0
  42. package/dist/internal/callerWatch.js +185 -0
  43. package/dist/internal/engine.d.ts +1305 -0
  44. package/dist/internal/engine.d.ts.map +1 -0
  45. package/dist/internal/engine.js +3458 -0
  46. package/dist/internal/errors.d.ts +1 -33
  47. package/dist/internal/errors.d.ts.map +1 -1
  48. package/dist/internal/errors.js +1 -45
  49. package/dist/internal/fixture.d.ts +2 -1
  50. package/dist/internal/fixture.d.ts.map +1 -1
  51. package/dist/internal/fixture.js +8 -4
  52. package/dist/internal/image.d.ts +4 -1
  53. package/dist/internal/image.d.ts.map +1 -1
  54. package/dist/internal/image.js +6 -3
  55. package/dist/internal/lines.d.ts.map +1 -1
  56. package/dist/internal/lines.js +3 -2
  57. package/dist/internal/liveImage.d.ts +4 -2
  58. package/dist/internal/liveImage.d.ts.map +1 -1
  59. package/dist/internal/liveImage.js +3 -1
  60. package/dist/internal/merkle.d.ts +7 -4
  61. package/dist/internal/merkle.d.ts.map +1 -1
  62. package/dist/internal/merkle.js +6 -4
  63. package/dist/internal/search.d.ts +3 -1
  64. package/dist/internal/search.d.ts.map +1 -1
  65. package/dist/internal/search.js +4 -3
  66. package/dist/internal/snapshotDelta.d.ts +11 -7
  67. package/dist/internal/snapshotDelta.d.ts.map +1 -1
  68. package/dist/internal/snapshotDelta.js +15 -9
  69. package/dist/internal/snapshotMerge.d.ts +1 -1
  70. package/dist/internal/snapshotMerge.d.ts.map +1 -1
  71. package/dist/internal/snapshotMerge.js +5 -2
  72. package/dist/internal/tree.d.ts +4 -2
  73. package/dist/internal/tree.d.ts.map +1 -1
  74. package/dist/internal/tree.js +4 -2
  75. package/dist/internal/virtualFileSystem.d.ts +20 -49
  76. package/dist/internal/virtualFileSystem.d.ts.map +1 -1
  77. package/dist/internal/virtualFileSystem.js +85 -1927
  78. package/dist/internal/volumeLimits.d.ts +1 -0
  79. package/dist/internal/volumeLimits.d.ts.map +1 -1
  80. package/dist/internal/volumeLimits.js +3 -2
  81. package/dist/internal/volumeState.d.ts +10 -79
  82. package/dist/internal/volumeState.d.ts.map +1 -1
  83. package/dist/internal/volumeState.js +9 -79
  84. package/dist/internal/watchHub.d.ts +9 -5
  85. package/dist/internal/watchHub.d.ts.map +1 -1
  86. package/dist/internal/watchHub.js +35 -8
  87. package/package.json +16 -9
  88. package/dist/internal/inodeTable.d.ts +0 -20
  89. package/dist/internal/inodeTable.d.ts.map +0 -1
  90. package/dist/internal/inodeTable.js +0 -48
  91. package/dist/internal/path.d.ts +0 -56
  92. package/dist/internal/path.d.ts.map +0 -1
  93. package/dist/internal/path.js +0 -141
  94. package/dist/internal/resolution.d.ts +0 -135
  95. package/dist/internal/resolution.d.ts.map +0 -1
  96. package/dist/internal/resolution.js +0 -277
  97. package/dist/internal/testSeams.d.ts +0 -17
  98. package/dist/internal/testSeams.d.ts.map +0 -1
  99. package/dist/internal/testSeams.js +0 -20
  100. package/dist/internal/tokenRegistry.d.ts +0 -77
  101. package/dist/internal/tokenRegistry.d.ts.map +0 -1
  102. package/dist/internal/tokenRegistry.js +0 -128
  103. package/dist/internal/turnstile.d.ts +0 -8
  104. package/dist/internal/turnstile.d.ts.map +0 -1
  105. 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
- };