@effect-vfs/core 0.7.1 → 0.9.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 (79) hide show
  1. package/README.md +21 -235
  2. package/dist/Caller.d.ts +2 -0
  3. package/dist/Caller.d.ts.map +1 -1
  4. package/dist/Caller.js +3 -1
  5. package/dist/LiveVolume.d.ts +69 -1
  6. package/dist/LiveVolume.d.ts.map +1 -1
  7. package/dist/LiveVolume.js +89 -12
  8. package/dist/Search.d.ts +730 -0
  9. package/dist/Search.d.ts.map +1 -0
  10. package/dist/Search.js +576 -0
  11. package/dist/SnapshotDelta.d.ts +234 -0
  12. package/dist/SnapshotDelta.d.ts.map +1 -1
  13. package/dist/SnapshotDelta.js +107 -0
  14. package/dist/VfsError.d.ts +3 -1
  15. package/dist/VfsError.d.ts.map +1 -1
  16. package/dist/VfsError.js +3 -1
  17. package/dist/VirtualFileSystem.d.ts +78 -2
  18. package/dist/VirtualFileSystem.d.ts.map +1 -1
  19. package/dist/VirtualFileSystem.js +68 -4
  20. package/dist/Watch.d.ts +18 -0
  21. package/dist/Watch.d.ts.map +1 -1
  22. package/dist/Watch.js +12 -0
  23. package/dist/index.d.ts +7 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +7 -0
  26. package/dist/internal/callerWatch.d.ts +32 -0
  27. package/dist/internal/callerWatch.d.ts.map +1 -0
  28. package/dist/internal/callerWatch.js +184 -0
  29. package/dist/internal/confinement.d.ts +16 -0
  30. package/dist/internal/confinement.d.ts.map +1 -0
  31. package/dist/internal/confinement.js +79 -0
  32. package/dist/internal/directoryEntries.d.ts +6 -0
  33. package/dist/internal/directoryEntries.d.ts.map +1 -0
  34. package/dist/internal/directoryEntries.js +79 -0
  35. package/dist/internal/fixture.js +4 -4
  36. package/dist/internal/glob.d.ts +66 -0
  37. package/dist/internal/glob.d.ts.map +1 -0
  38. package/dist/internal/glob.js +248 -0
  39. package/dist/internal/image.d.ts +7 -1
  40. package/dist/internal/image.d.ts.map +1 -1
  41. package/dist/internal/image.js +9 -7
  42. package/dist/internal/liveImage.d.ts +1 -1
  43. package/dist/internal/liveImage.d.ts.map +1 -1
  44. package/dist/internal/liveImage.js +2 -10
  45. package/dist/internal/path.js +2 -2
  46. package/dist/internal/resolution.d.ts +139 -0
  47. package/dist/internal/resolution.d.ts.map +1 -0
  48. package/dist/internal/resolution.js +332 -0
  49. package/dist/internal/search.d.ts +24 -0
  50. package/dist/internal/search.d.ts.map +1 -0
  51. package/dist/internal/search.js +78 -0
  52. package/dist/internal/searchContent.d.ts +77 -0
  53. package/dist/internal/searchContent.d.ts.map +1 -0
  54. package/dist/internal/searchContent.js +223 -0
  55. package/dist/internal/searchModel.d.ts +83 -0
  56. package/dist/internal/searchModel.d.ts.map +1 -0
  57. package/dist/internal/searchModel.js +23 -0
  58. package/dist/internal/snapshotDelta.d.ts +470 -1
  59. package/dist/internal/snapshotDelta.d.ts.map +1 -1
  60. package/dist/internal/snapshotDelta.js +59 -25
  61. package/dist/internal/snapshotMerge.d.ts +54 -0
  62. package/dist/internal/snapshotMerge.d.ts.map +1 -0
  63. package/dist/internal/snapshotMerge.js +959 -0
  64. package/dist/internal/tokenRegistry.d.ts +83 -0
  65. package/dist/internal/tokenRegistry.d.ts.map +1 -0
  66. package/dist/internal/tokenRegistry.js +146 -0
  67. package/dist/internal/virtualFileSystem.d.ts +32 -17
  68. package/dist/internal/virtualFileSystem.d.ts.map +1 -1
  69. package/dist/internal/virtualFileSystem.js +503 -736
  70. package/dist/internal/volumeLimits.d.ts +53 -0
  71. package/dist/internal/volumeLimits.d.ts.map +1 -0
  72. package/dist/internal/volumeLimits.js +63 -0
  73. package/dist/internal/volumeState.d.ts +2 -0
  74. package/dist/internal/volumeState.d.ts.map +1 -1
  75. package/dist/internal/volumeState.js +9 -0
  76. package/dist/internal/watchHub.d.ts +6 -2
  77. package/dist/internal/watchHub.d.ts.map +1 -1
  78. package/dist/internal/watchHub.js +31 -6
  79. package/package.json +9 -3
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Compiles bounded Unicode namespace globs and meters scalar matching work.
3
+ *
4
+ * @internal
5
+ * @since 0.1.0
6
+ */
7
+ import * as ByteSize from "effect/ByteSize";
8
+ import * as Effect from "effect/Effect";
9
+ import { BudgetExceeded, type Meter, QueryFailure } from "./searchModel.js";
10
+ type Atom = {
11
+ readonly low: number;
12
+ readonly high: number;
13
+ };
14
+ type Token = {
15
+ readonly tag: "literal";
16
+ readonly value: string;
17
+ } | {
18
+ readonly tag: "star";
19
+ } | {
20
+ readonly tag: "any";
21
+ } | {
22
+ readonly tag: "class";
23
+ readonly atoms: ReadonlyArray<Atom>;
24
+ readonly negate: boolean;
25
+ };
26
+ type Segment = ReadonlyArray<Token> | "**";
27
+ interface Pattern {
28
+ readonly segments: ReadonlyArray<Segment>;
29
+ readonly directory: boolean;
30
+ }
31
+ /** @internal */
32
+ export interface CompiledSelectors {
33
+ readonly include: ReadonlyArray<Pattern>;
34
+ readonly exclude: ReadonlyArray<Pattern>;
35
+ }
36
+ /** @internal */
37
+ export declare const compile: (selectors: {
38
+ readonly include: ReadonlyArray<string>;
39
+ readonly exclude?: ReadonlyArray<string>;
40
+ }, limits: {
41
+ readonly maxEntries: number;
42
+ readonly maxDepth: number;
43
+ readonly maxPathBytes: ByteSize.ByteSize;
44
+ readonly maxResults: number;
45
+ readonly maxResultBytes: ByteSize.ByteSize;
46
+ readonly maxPatternBytes: ByteSize.ByteSize;
47
+ readonly maxPatterns: number;
48
+ readonly maxPatternListBytes: ByteSize.ByteSize;
49
+ readonly maxExpansions: number;
50
+ readonly maxTokens: number;
51
+ readonly maxMatchingWork: number;
52
+ readonly maxScannedBytes: ByteSize.ByteSize;
53
+ readonly maxFileBytes: ByteSize.ByteSize;
54
+ readonly maxLineEvaluations: number;
55
+ readonly maxExcerptBytes: ByteSize.ByteSize;
56
+ }) => Effect.Effect<{
57
+ include: Pattern[];
58
+ exclude: Pattern[];
59
+ }, QueryFailure, never>;
60
+ /** @internal */
61
+ export declare const matches: (compiled: CompiledSelectors, parts: readonly string[], kind: "directory" | "file" | "symlink", meter: Meter) => Effect.Effect<{
62
+ excluded: boolean;
63
+ included: boolean;
64
+ }, BudgetExceeded, never>;
65
+ export {};
66
+ //# sourceMappingURL=glob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../src/internal/glob.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAA0B,KAAK,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEnG,KAAK,IAAI,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3D,KAAK,KAAK,GACN;IAAE,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACxB;IAAE,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAA;CAAE,GACvB;IAAE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAAA;AAE5F,KAAK,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CAAA;AAE1C,UAAU,OAAO;IACf,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IACzC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;CAC5B;AAED,gBAAgB;AAChB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IACxC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;CACzC;AAED,gBAAgB;AAChB,eAAO,MAAM,OAAO;sBACa,aAAa,CAAC,MAAM,CAAC;uBAAqB,aAAa,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;uBAqM9F,CAAA;AAEF,gBAAgB;AAChB,eAAO,MAAM,OAAO;;;yBAoFnB,CAAA"}
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Compiles bounded Unicode namespace globs and meters scalar matching work.
3
+ *
4
+ * @internal
5
+ * @since 0.1.0
6
+ */
7
+ import * as ByteSize from "effect/ByteSize";
8
+ import * as Effect from "effect/Effect";
9
+ import { BudgetExceeded, QueryFailure } from "./searchModel.js";
10
+ /** @internal */
11
+ export const compile = Effect.fnUntraced(function* (selectors, limits) {
12
+ const fail = (pattern, message, limit) => limit === undefined
13
+ ? new QueryFailure({ field: "patterns", pattern, message })
14
+ : new QueryFailure({ field: "patterns", pattern, message, limit });
15
+ if (selectors.include.length === 0)
16
+ return yield* fail("", "At least one include pattern is required");
17
+ if (selectors.include.length + (selectors.exclude?.length ?? 0) > limits.maxPatterns) {
18
+ return yield* fail("", "Too many patterns", "maxPatterns");
19
+ }
20
+ const sources = [...selectors.include, ...selectors.exclude ?? []];
21
+ let bytes = 0n;
22
+ let expansions = 0;
23
+ let tokens = 0;
24
+ let steps = 0;
25
+ const include = [];
26
+ const exclude = [];
27
+ for (let sourceIndex = 0; sourceIndex < sources.length; sourceIndex++) {
28
+ const source = sources[sourceIndex];
29
+ // Count scalar UTF-8 bytes before allocating expanded patterns.
30
+ let sourceBytes = 0n;
31
+ for (const scalar of source) {
32
+ const point = scalar.codePointAt(0);
33
+ if (point === 0 || point >= 0xd800 && point <= 0xdfff) {
34
+ return yield* fail(source, "Patterns require Unicode scalar values without NUL");
35
+ }
36
+ sourceBytes += BigInt(point <= 0x7f ? 1 : point <= 0x7ff ? 2 : point <= 0xffff ? 3 : 4);
37
+ if (sourceBytes > ByteSize.toBigInt(limits.maxPatternBytes)) {
38
+ return yield* fail(source, "Pattern byte limit exceeded", "maxPatternBytes");
39
+ }
40
+ if (++steps % 128 === 0)
41
+ yield* Effect.yieldNow;
42
+ }
43
+ bytes += sourceBytes;
44
+ if (bytes > ByteSize.toBigInt(limits.maxPatternListBytes)) {
45
+ return yield* fail(source, "Pattern list byte limit exceeded", "maxPatternListBytes");
46
+ }
47
+ const pending = [source];
48
+ const expanded = [];
49
+ while (pending.length > 0) {
50
+ const value = pending.pop();
51
+ const stack = [];
52
+ let choice;
53
+ let inClass = false;
54
+ for (let i = 0; i < value.length; i++) {
55
+ const char = value[i];
56
+ if (++steps % 128 === 0)
57
+ yield* Effect.yieldNow;
58
+ if (char === "\\") {
59
+ i++;
60
+ continue;
61
+ }
62
+ if (char === "[")
63
+ inClass = true;
64
+ if (char === "]")
65
+ inClass = false;
66
+ if (inClass)
67
+ continue;
68
+ if (char === "{")
69
+ stack.push({ start: i, commas: [] });
70
+ else if (char === "," && stack.length > 0)
71
+ stack[stack.length - 1].commas.push(i);
72
+ else if (char === "}") {
73
+ const open = stack.pop();
74
+ if (open === undefined)
75
+ return yield* fail(source, "Unmatched closing brace");
76
+ // Expand outer choices first so nested braces cannot duplicate sibling alternatives.
77
+ if (open.commas.length > 0 && (choice === undefined || open.start < choice.start)) {
78
+ choice = { ...open, end: i };
79
+ }
80
+ }
81
+ }
82
+ if (stack.length > 0)
83
+ return yield* fail(source, "Unclosed brace");
84
+ if (choice === undefined) {
85
+ if (++expansions > limits.maxExpansions)
86
+ return yield* fail(source, "Expansion limit exceeded", "maxExpansions");
87
+ expanded.push(value);
88
+ }
89
+ else {
90
+ const boundaries = [choice.start, ...choice.commas, choice.end];
91
+ if (expansions + pending.length + boundaries.length - 1 > limits.maxExpansions) {
92
+ return yield* fail(source, "Expansion limit exceeded", "maxExpansions");
93
+ }
94
+ for (let i = boundaries.length - 2; i >= 0; i--) {
95
+ pending.push(value.slice(0, choice.start) + value.slice(boundaries[i] + 1, boundaries[i + 1]) +
96
+ value.slice(choice.end + 1));
97
+ }
98
+ }
99
+ }
100
+ for (const value of expanded) {
101
+ const directory = value.endsWith("/");
102
+ const pieces = (directory ? value.slice(0, -1) : value).split("/");
103
+ const segments = [];
104
+ for (const piece of pieces) {
105
+ if (piece === "" || piece === "." || piece === "..") {
106
+ return yield* fail(source, "Empty, absolute and dot segments are unsupported");
107
+ }
108
+ if (piece === "**") {
109
+ if (++tokens > limits.maxTokens)
110
+ return yield* fail(source, "Token limit exceeded", "maxTokens");
111
+ segments.push("**");
112
+ continue;
113
+ }
114
+ const scalars = Array.from(piece);
115
+ const segment = [];
116
+ for (let i = 0; i < scalars.length; i++) {
117
+ const scalar = scalars[i];
118
+ if (++tokens > limits.maxTokens)
119
+ return yield* fail(source, "Token limit exceeded", "maxTokens");
120
+ if (scalar === "\\") {
121
+ const next = scalars[++i];
122
+ if (next === undefined)
123
+ return yield* fail(source, "Dangling escape");
124
+ segment.push({ tag: "literal", value: next });
125
+ }
126
+ else if (scalar === "*") {
127
+ if (scalars[i + 1] === "*")
128
+ return yield* fail(source, "Globstar must occupy a whole segment");
129
+ segment.push({ tag: "star" });
130
+ }
131
+ else if (scalar === "?")
132
+ segment.push({ tag: "any" });
133
+ else if (scalar === "[") {
134
+ const negate = scalars[i + 1] === "!";
135
+ if (negate)
136
+ i++;
137
+ const atoms = [];
138
+ const read = () => {
139
+ let char = scalars[++i];
140
+ if (char === "\\")
141
+ char = scalars[++i];
142
+ return char?.codePointAt(0);
143
+ };
144
+ while (scalars[i + 1] !== "]") {
145
+ const low = read();
146
+ if (low === undefined)
147
+ return yield* fail(source, "Unclosed character class");
148
+ let high = low;
149
+ if (scalars[i + 1] === "-" && scalars[i + 2] !== "]") {
150
+ i++;
151
+ const end = read();
152
+ if (end === undefined || end < low)
153
+ return yield* fail(source, "Invalid character range");
154
+ high = end;
155
+ }
156
+ if (++tokens > limits.maxTokens)
157
+ return yield* fail(source, "Token limit exceeded", "maxTokens");
158
+ atoms.push({ low, high });
159
+ if (++steps % 128 === 0)
160
+ yield* Effect.yieldNow;
161
+ }
162
+ i++;
163
+ if (atoms.length === 0)
164
+ return yield* fail(source, "Empty character class");
165
+ segment.push({ tag: "class", atoms, negate });
166
+ }
167
+ else
168
+ segment.push({ tag: "literal", value: scalar });
169
+ if (++steps % 128 === 0)
170
+ yield* Effect.yieldNow;
171
+ }
172
+ segments.push(segment);
173
+ }
174
+ ;
175
+ (sourceIndex < selectors.include.length ? include : exclude).push({ segments, directory });
176
+ }
177
+ }
178
+ return { include, exclude };
179
+ });
180
+ /** @internal */
181
+ export const matches = Effect.fnUntraced(function* (compiled, parts, kind, meter) {
182
+ const path = parts.join("/");
183
+ const tick = Effect.fnUntraced(function* () {
184
+ if (meter.work.matchingWork >= meter.limits.maxMatchingWork) {
185
+ return yield* new BudgetExceeded({ limit: "maxMatchingWork", path });
186
+ }
187
+ meter.work.matchingWork++;
188
+ if (meter.work.matchingWork % 128 === 0)
189
+ yield* Effect.yieldNow;
190
+ });
191
+ const segmentMatches = Effect.fnUntraced(function* (tokens, text) {
192
+ const scalars = Array.from(text);
193
+ let previous = [true, ...scalars.map(() => false)];
194
+ for (const token of tokens) {
195
+ const next = scalars.map(() => false);
196
+ next.push(false);
197
+ for (let i = 0; i <= scalars.length; i++) {
198
+ yield* tick();
199
+ if (token.tag === "star")
200
+ next[i] = previous[i] || i > 0 && next[i - 1];
201
+ else if (i > 0 && previous[i - 1]) {
202
+ if (token.tag === "any")
203
+ next[i] = true;
204
+ else if (token.tag === "literal")
205
+ next[i] = token.value === scalars[i - 1];
206
+ else {
207
+ const point = scalars[i - 1].codePointAt(0);
208
+ let found = false;
209
+ for (const atom of token.atoms) {
210
+ yield* tick();
211
+ if (point >= atom.low && point <= atom.high) {
212
+ found = true;
213
+ break;
214
+ }
215
+ }
216
+ next[i] = token.negate ? !found : found;
217
+ }
218
+ }
219
+ }
220
+ previous = next;
221
+ }
222
+ return previous[scalars.length];
223
+ });
224
+ const any = Effect.fnUntraced(function* (patterns) {
225
+ for (const pattern of patterns) {
226
+ yield* tick();
227
+ if (pattern.directory && kind !== "directory")
228
+ continue;
229
+ let previous = [true, ...parts.map(() => false)];
230
+ for (const segment of pattern.segments) {
231
+ const next = parts.map(() => false);
232
+ next.push(false);
233
+ for (let i = 0; i <= parts.length; i++) {
234
+ yield* tick();
235
+ next[i] = segment === "**"
236
+ ? previous[i] || i > 0 && next[i - 1]
237
+ : i > 0 && previous[i - 1] && (yield* segmentMatches(segment, parts[i - 1]));
238
+ }
239
+ previous = next;
240
+ }
241
+ if (previous[parts.length])
242
+ return true;
243
+ }
244
+ return false;
245
+ });
246
+ const excluded = yield* any(compiled.exclude);
247
+ return { excluded, included: excluded ? false : yield* any(compiled.include) };
248
+ });
@@ -1,4 +1,5 @@
1
1
  import * as Effect from "effect/Effect";
2
+ import * as Result from "effect/Result";
2
3
  import type * as Sink from "effect/Sink";
3
4
  import * as Stream from "effect/Stream";
4
5
  import type { FixtureEntry } from "../Fixture.js";
@@ -6,7 +7,7 @@ import { type Snapshot } from "../Snapshot.js";
6
7
  import type { FsFailure, ImageFailure } from "../VfsError.js";
7
8
  import type { PathInput } from "../VirtualFileSystem.js";
8
9
  import type { Budget } from "./budget.js";
9
- import { type VolumeState } from "./volumeState.js";
10
+ import { type Node, type VolumeState } from "./volumeState.js";
10
11
  /** @internal */
11
12
  export declare const make: (value: VolumeState) => Snapshot;
12
13
  /** @internal */
@@ -18,5 +19,10 @@ export declare const encodeSnapshot: (snapshot: Snapshot, budget?: Budget) => Ef
18
19
  /** @internal */
19
20
  export declare const decodeSnapshotSink: (budget: Budget) => Sink.Sink<Snapshot, Uint8Array, never, ImageFailure>;
20
21
  /** @internal */
22
+ export declare const resolve: (value: VolumeState, input: PathInput, options: {
23
+ readonly operation: string;
24
+ readonly followFinalSymlink: boolean;
25
+ }) => Result.Result<Node, FsFailure>;
26
+ /** @internal */
21
27
  export declare const snapshotEntries: (snapshot: Snapshot, root: PathInput) => Stream.Stream<FixtureEntry, FsFailure | ImageFailure>;
22
28
  //# sourceMappingURL=image.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/internal/image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAKvC,OAAO,KAAK,KAAK,IAAI,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,gBAAgB,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAezC,OAAO,EAQL,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAA;AAgBzB,gBAAgB;AAChB,eAAO,MAAM,IAAI,UAAW,WAAW,KAAG,QAAkD,CAAA;AAE5F,gBAAgB;AAChB,eAAO,MAAM,OAAO,aAAc,QAAQ,KAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAOhF,CAAA;AAOJ,gBAAgB;AAChB,eAAO,MAAM,oBAAoB,aACrB,QAAQ,WACT,MAAM,KACd,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CAapC,CAAA;AAEL,gBAAgB;AAChB,eAAO,MAAM,cAAc,aAAc,QAAQ,WAAW,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CACpD,CAAA;AAEvD,gBAAgB;AAChB,eAAO,MAAM,kBAAkB,WAAY,MAAM,KAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,CAYtG,CAAA;AA0GD,gBAAgB;AAChB,eAAO,MAAM,eAAe,aAChB,QAAQ,QACZ,SAAS,KACd,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,GAAG,YAAY,CAOlD,CAAA"}
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../src/internal/image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,KAAK,IAAI,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,gBAAgB,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAezC,OAAO,EAKL,KAAK,IAAI,EAGT,KAAK,WAAW,EACjB,MAAM,kBAAkB,CAAA;AAgBzB,gBAAgB;AAChB,eAAO,MAAM,IAAI,UAAW,WAAW,KAAG,QAAkD,CAAA;AAE5F,gBAAgB;AAChB,eAAO,MAAM,OAAO,aAAc,QAAQ,KAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAOhF,CAAA;AAOJ,gBAAgB;AAChB,eAAO,MAAM,oBAAoB,aACrB,QAAQ,WACT,MAAM,KACd,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CAapC,CAAA;AAEL,gBAAgB;AAChB,eAAO,MAAM,cAAc,aAAc,QAAQ,WAAW,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CACpD,CAAA;AAEvD,gBAAgB;AAChB,eAAO,MAAM,kBAAkB,WAAY,MAAM,KAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,CAYtG,CAAA;AAOD,gBAAgB;AAChB,eAAO,MAAM,OAAO,UACX,WAAW,SACX,SAAS,WACP;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAA;CAAE,KAC5E,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAmD/B,CAAA;AAmDD,gBAAgB;AAChB,eAAO,MAAM,eAAe,aAChB,QAAQ,QACZ,SAAS,KACd,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,GAAG,YAAY,CAOlD,CAAA"}
@@ -64,10 +64,11 @@ export const decodeSnapshotSink = (budget) => {
64
64
  };
65
65
  const OPERATION = "snapshotEntries";
66
66
  const encoder = new TextEncoder();
67
- // Match privileged lookup: follow intermediate links, honor trailing slashes, and leave the final link intact.
68
- const resolve = (value, input) => {
69
- const fail = (code) => Result.fail(fsFailure(code, OPERATION, { path: input }));
70
- const prepared = preparePath(input, OPERATION, undefined);
67
+ // Privileged immutable lookup follows intermediate links and honors trailing slashes.
68
+ /** @internal */
69
+ export const resolve = (value, input, options) => {
70
+ const fail = (code) => Result.fail(fsFailure(code, options.operation, { path: input }));
71
+ const prepared = preparePath(input, options.operation, undefined);
71
72
  if (Result.isFailure(prepared))
72
73
  return Result.fail(prepared.failure);
73
74
  const root = getNode(value, ROOT_INO);
@@ -88,7 +89,8 @@ const resolve = (value, input) => {
88
89
  const child = ino === undefined ? undefined : getNode(value, ino);
89
90
  if (child === undefined)
90
91
  return fail("NotFound");
91
- if (child.kind !== "symlink" || (index === work.components.length - 1 && !work.trailingSlash)) {
92
+ if (child.kind !== "symlink" ||
93
+ (index === work.components.length - 1 && !work.trailingSlash && !options.followFinalSymlink)) {
92
94
  current = child;
93
95
  continue;
94
96
  }
@@ -100,7 +102,7 @@ const resolve = (value, input) => {
100
102
  const expansion = new Uint8Array(child.target.length + suffix.length);
101
103
  expansion.set(child.target);
102
104
  expansion.set(suffix, child.target.length);
103
- const expanded = preparePath(ownedPath(expansion), OPERATION, undefined);
105
+ const expanded = preparePath(ownedPath(expansion), options.operation, undefined);
104
106
  if (Result.isFailure(expanded))
105
107
  return fail(expanded.failure.code);
106
108
  work = expanded.success;
@@ -151,7 +153,7 @@ function* walk(value, node) {
151
153
  /** @internal */
152
154
  export const snapshotEntries = (snapshot, root) => Stream.unwrap(Effect.gen(function* () {
153
155
  const value = yield* valueOf(snapshot);
154
- const node = yield* Effect.fromResult(resolve(value, root));
156
+ const node = yield* Effect.fromResult(resolve(value, root, { operation: OPERATION, followFinalSymlink: false }));
155
157
  // Bound each pulled chunk to one file's copied bytes.
156
158
  return Stream.fromIterable({ [Symbol.iterator]: () => walk(value, node) }, { chunkSize: 1 });
157
159
  }));
@@ -1,4 +1,4 @@
1
- import * as ByteSize from "effect/ByteSize";
1
+ import type * as ByteSize from "effect/ByteSize";
2
2
  import * as Effect from "effect/Effect";
3
3
  import type { VolumeLimits } from "../VirtualFileSystem.js";
4
4
  import type { VolumeIdentity } from "../Volume.js";
@@ -1 +1 @@
1
- {"version":3,"file":"liveImage.d.ts","sourceRoot":"","sources":["../../src/internal/liveImage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAIvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAqC,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAKxG,gBAAgB;AAChB,eAAO,MAAM,aAAa,UAAW,WAAW,KAAG,KAAK,CAAC,WAAW,CAUnE,CAAA;AAED,KAAK,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE1C,gBAAgB;AAChB,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;CAC9B;AAED,gBAAgB;AAChB,MAAM,WAAW,QAAS,SAAQ,MAAM;IACtC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC9B;AAQD,gBAAgB;AAChB,eAAO,MAAM,MAAM,wJAwCjB,CAAA;AAWF,gBAAgB;AAChB,eAAO,MAAM,MAAM,UAAW,UAAU,mBAAmB,QAAQ,CAAC,QAAQ,0EAyBzE,CAAA"}
1
+ {"version":3,"file":"liveImage.d.ts","sourceRoot":"","sources":["../../src/internal/liveImage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAChD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAIvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAqC,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAKxG,gBAAgB;AAChB,eAAO,MAAM,aAAa,UAAW,WAAW,KAAG,KAAK,CAAC,WAAW,CAUnE,CAAA;AAED,KAAK,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE1C,gBAAgB;AAChB,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;CAC9B;AAED,gBAAgB;AAChB,MAAM,WAAW,QAAS,SAAQ,MAAM;IACtC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAA;CAC9B;AAQD,gBAAgB;AAChB,eAAO,MAAM,MAAM,wJAgCjB,CAAA;AAWF,gBAAgB;AAChB,eAAO,MAAM,MAAM,UAAW,UAAU,mBAAmB,QAAQ,CAAC,QAAQ,0EAyBzE,CAAA"}
@@ -1,11 +1,10 @@
1
- // Live images persist runtime identity and revisions along with the tree, including unlinked open files.
2
- import * as ByteSize from "effect/ByteSize";
3
1
  import * as Effect from "effect/Effect";
4
2
  import * as Result from "effect/Result";
5
3
  import * as Schema from "effect/Schema";
6
4
  import * as Stream from "effect/Stream";
7
5
  import * as Lines from "./lines.js";
8
6
  import * as Tree from "./tree.js";
7
+ import * as Limits from "./volumeLimits.js";
9
8
  import { assemble, getNode, Ino } from "./volumeState.js";
10
9
  const OPERATION = "openImage";
11
10
  const DOCUMENT_FIELD = "liveImage";
@@ -25,14 +24,7 @@ const liveNode = (node) => ({ ...Tree.treeNode(node), rev: node.revision });
25
24
  /** @internal */
26
25
  export const encode = Effect.fnUntraced(function* (state, { epoch, identity, keySecret }, limits) {
27
26
  const nodes = yield* Tree.treeNodes(state, retainedFiles(state));
28
- const stored = {};
29
- if (limits.maxEntries !== undefined)
30
- stored.maxEntries = limits.maxEntries;
31
- if (limits.maxBytes !== undefined)
32
- stored.maxBytes = ByteSize.toBigInt(limits.maxBytes);
33
- stored.maxFileBytes = ByteSize.toBigInt(limits.maxFileBytes);
34
- if (limits.maxPathBytes !== undefined)
35
- stored.maxPathBytes = ByteSize.toBigInt(limits.maxPathBytes);
27
+ const stored = Limits.toStored(limits);
36
28
  const header = yield* Effect.fromResult(headerText({
37
29
  format: "effect-vfs-live",
38
30
  version: 1,
@@ -63,7 +63,7 @@ const attachedBuffer = (bytes) => {
63
63
  /** @internal */
64
64
  export const isAttachedBytes = (bytes) => Predicate.isUint8Array(bytes) && bytes.buffer instanceof ArrayBuffer && attachedBuffer(bytes);
65
65
  /** @internal */
66
- export const pathFromBytes = Effect.fn("VirtualFileSystem.pathFromBytes")(function* (bytes) {
66
+ export const pathFromBytes = Effect.fnUntraced(function* (bytes) {
67
67
  if (!isAttachedBytes(bytes))
68
68
  return yield* fsFailure("InvalidArgument", "pathFromBytes");
69
69
  const owned = new Uint8Array(bytes);
@@ -73,7 +73,7 @@ export const pathFromBytes = Effect.fn("VirtualFileSystem.pathFromBytes")(functi
73
73
  return makeBytePath(owned);
74
74
  });
75
75
  /** @internal */
76
- export const pathToBytes = Effect.fn("VirtualFileSystem.pathToBytes")(function* (path) {
76
+ export const pathToBytes = Effect.fnUntraced(function* (path) {
77
77
  const bytes = getBytePathBytes(path);
78
78
  if (bytes === undefined)
79
79
  return yield* fsFailure("InvalidArgument", "pathToBytes");
@@ -0,0 +1,139 @@
1
+ import * as ByteSize from "effect/ByteSize";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Result from "effect/Result";
4
+ import type { Identity } from "../Caller.js";
5
+ import { type EntryInput, type NameInput, type Target } from "../Target.js";
6
+ import type { FsFailure } from "../VfsError.js";
7
+ import type { DirectoryHandle, FileHandle, PathInput } from "../VirtualFileSystem.js";
8
+ import { type Confinement } from "./confinement.js";
9
+ import type { OpContext } from "./errors.js";
10
+ import { type PreparedPath } from "./path.js";
11
+ import * as TokenRegistry from "./tokenRegistry.js";
12
+ import { type Directory, type Ino, type Node } from "./volumeState.js";
13
+ /** @internal */
14
+ export type PreparedEntry = {
15
+ readonly kind: "path";
16
+ readonly path: PreparedPath;
17
+ readonly base: DirectoryHandle | undefined;
18
+ } | {
19
+ readonly kind: "entry";
20
+ readonly directory: Target;
21
+ readonly name: string;
22
+ };
23
+ /** @internal */
24
+ export interface NodeMode<R = never> {
25
+ readonly kind: "Node";
26
+ readonly followFinalSymlink?: boolean;
27
+ readonly final?: boolean;
28
+ readonly createMissing?: (parent: Directory, name: string, final: boolean) => Effect.Effect<Directory, FsFailure, R>;
29
+ }
30
+ /** @internal */
31
+ export interface ParentMode {
32
+ readonly kind: "Parent";
33
+ }
34
+ /** @internal */
35
+ export interface OrCreateMode<R = never> {
36
+ readonly kind: "OrCreate";
37
+ readonly create: "never" | "ifMissing" | "exclusive";
38
+ readonly finalSymlink: "follow" | "preserve";
39
+ readonly entryExclusive?: "afterSymlink";
40
+ readonly beforeFollow?: (parent: Directory, child: Node | undefined) => Effect.Effect<void, FsFailure, R>;
41
+ }
42
+ /** @internal */
43
+ export type NodeResult = {
44
+ readonly kind: "node";
45
+ readonly node: Node;
46
+ readonly op: OpContext;
47
+ } | {
48
+ readonly kind: "entry";
49
+ readonly node: Node;
50
+ readonly parent: Directory;
51
+ readonly name: string;
52
+ readonly op: OpContext;
53
+ };
54
+ /** @internal */
55
+ export interface ParentResult {
56
+ readonly kind: "parent";
57
+ readonly parent: Ino;
58
+ readonly name: string | undefined;
59
+ readonly trailingSlash: boolean;
60
+ readonly addressing: "path" | "entry";
61
+ readonly op: OpContext;
62
+ }
63
+ interface CreateEntry {
64
+ readonly parent: Directory;
65
+ readonly name: string;
66
+ readonly trailingSlash: boolean;
67
+ readonly addressing: "path" | "entry";
68
+ readonly op: OpContext;
69
+ readonly origin: {
70
+ readonly parent: Directory;
71
+ readonly name: string;
72
+ };
73
+ }
74
+ /** @internal */
75
+ export type CreateResult = (CreateEntry & {
76
+ readonly kind: "existing";
77
+ readonly node: Node;
78
+ }) | (CreateEntry & {
79
+ readonly kind: "missing";
80
+ });
81
+ /** @internal */
82
+ export declare const inGroup: (identity: Identity, gid: number) => boolean;
83
+ /** @internal */
84
+ export declare const permitted: (node: Node, identity: Identity) => number;
85
+ /** @internal */
86
+ export declare const authorize: (node: Node, identity: Identity, bits: number, op: OpContext) => Effect.Effect<void, never, never> | Effect.Effect<never, FsFailure, never>;
87
+ /** @internal */
88
+ export declare const entryName: (input: NameInput, op: OpContext) => Result.Result<string, FsFailure>;
89
+ /** @internal */
90
+ export declare const make: ({ caller, get, identity, maxPathBytes, registry, confinement, additional, authorityView }: {
91
+ readonly additional?: ReadonlyArray<Confinement> | undefined;
92
+ readonly authorityView: Effect.Effect<(ino: Ino) => Node | undefined>;
93
+ readonly confinement?: Confinement | undefined;
94
+ readonly caller: TokenRegistry.DirectoryReference;
95
+ readonly get: (ino: Ino) => Effect.Effect<Node | undefined>;
96
+ readonly identity: Identity;
97
+ readonly maxPathBytes: ByteSize.ByteSize | undefined;
98
+ readonly registry: TokenRegistry.TokenRegistry;
99
+ }) => {
100
+ prepare: (input: PathInput, op: OpContext) => Result.Result<PreparedPath, FsFailure>;
101
+ prepareEntry: (input: EntryInput, op: OpContext) => Result.Result<PreparedEntry, FsFailure>;
102
+ resolve: {
103
+ <R = never>(target: Target, mode: NodeMode<R>, op: OpContext): Effect.Effect<NodeResult, FsFailure, R>;
104
+ (prepared: PreparedEntry, mode: ParentMode, op: OpContext): Effect.Effect<ParentResult, FsFailure>;
105
+ <R = never>(prepared: PreparedEntry, mode: OrCreateMode<R>, op: OpContext): Effect.Effect<CreateResult, FsFailure, R>;
106
+ };
107
+ directory: (target: {
108
+ readonly _tag: "Handle";
109
+ readonly handle: FileHandle | DirectoryHandle;
110
+ } | {
111
+ readonly _tag: "Path";
112
+ readonly path: PathInput;
113
+ readonly relativeTo?: DirectoryHandle;
114
+ readonly followFinalSymlink?: boolean;
115
+ } | {
116
+ readonly _tag: "Reference";
117
+ readonly reference: import("../VirtualFileSystem.js").ObjectReference;
118
+ }, op: OpContext) => Effect.Effect<{
119
+ node: Directory;
120
+ op: OpContext;
121
+ }, FsFailure, never>;
122
+ entryDirectory: (target: {
123
+ readonly _tag: "Handle";
124
+ readonly handle: FileHandle | DirectoryHandle;
125
+ } | {
126
+ readonly _tag: "Path";
127
+ readonly path: PathInput;
128
+ readonly relativeTo?: DirectoryHandle;
129
+ readonly followFinalSymlink?: boolean;
130
+ } | {
131
+ readonly _tag: "Reference";
132
+ readonly reference: import("../VirtualFileSystem.js").ObjectReference;
133
+ }, op: OpContext) => Effect.Effect<{
134
+ node: Directory;
135
+ op: OpContext;
136
+ }, FsFailure, never>;
137
+ };
138
+ export {};
139
+ //# sourceMappingURL=resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolution.d.ts","sourceRoot":"","sources":["../../src/internal/resolution.ts"],"names":[],"mappings":"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"}