@effect-vfs/core 0.7.0 → 0.8.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 (61) hide show
  1. package/README.md +15 -238
  2. package/dist/LiveVolume.d.ts.map +1 -1
  3. package/dist/LiveVolume.js +9 -9
  4. package/dist/Search.d.ts +730 -0
  5. package/dist/Search.d.ts.map +1 -0
  6. package/dist/Search.js +568 -0
  7. package/dist/SnapshotDelta.d.ts +234 -0
  8. package/dist/SnapshotDelta.d.ts.map +1 -1
  9. package/dist/SnapshotDelta.js +107 -0
  10. package/dist/VirtualFileSystem.d.ts +53 -1
  11. package/dist/VirtualFileSystem.d.ts.map +1 -1
  12. package/dist/VirtualFileSystem.js +59 -1
  13. package/dist/index.d.ts +7 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +7 -0
  16. package/dist/internal/canonicalBase64.js +3 -3
  17. package/dist/internal/fixture.js +3 -3
  18. package/dist/internal/glob.d.ts +66 -0
  19. package/dist/internal/glob.d.ts.map +1 -0
  20. package/dist/internal/glob.js +248 -0
  21. package/dist/internal/image.d.ts +7 -1
  22. package/dist/internal/image.d.ts.map +1 -1
  23. package/dist/internal/image.js +9 -7
  24. package/dist/internal/liveImage.d.ts +1 -1
  25. package/dist/internal/liveImage.d.ts.map +1 -1
  26. package/dist/internal/liveImage.js +2 -10
  27. package/dist/internal/overlayDiff.js +2 -2
  28. package/dist/internal/path.d.ts.map +1 -1
  29. package/dist/internal/path.js +3 -3
  30. package/dist/internal/resolution.d.ts +135 -0
  31. package/dist/internal/resolution.d.ts.map +1 -0
  32. package/dist/internal/resolution.js +277 -0
  33. package/dist/internal/search.d.ts +24 -0
  34. package/dist/internal/search.d.ts.map +1 -0
  35. package/dist/internal/search.js +78 -0
  36. package/dist/internal/searchContent.d.ts +77 -0
  37. package/dist/internal/searchContent.d.ts.map +1 -0
  38. package/dist/internal/searchContent.js +223 -0
  39. package/dist/internal/searchModel.d.ts +83 -0
  40. package/dist/internal/searchModel.d.ts.map +1 -0
  41. package/dist/internal/searchModel.js +23 -0
  42. package/dist/internal/snapshotDelta.d.ts +470 -1
  43. package/dist/internal/snapshotDelta.d.ts.map +1 -1
  44. package/dist/internal/snapshotDelta.js +60 -26
  45. package/dist/internal/snapshotMerge.d.ts +54 -0
  46. package/dist/internal/snapshotMerge.d.ts.map +1 -0
  47. package/dist/internal/snapshotMerge.js +959 -0
  48. package/dist/internal/tokenRegistry.d.ts +77 -0
  49. package/dist/internal/tokenRegistry.d.ts.map +1 -0
  50. package/dist/internal/tokenRegistry.js +128 -0
  51. package/dist/internal/tree.js +2 -2
  52. package/dist/internal/virtualFileSystem.d.ts +32 -17
  53. package/dist/internal/virtualFileSystem.d.ts.map +1 -1
  54. package/dist/internal/virtualFileSystem.js +640 -993
  55. package/dist/internal/volumeLimits.d.ts +53 -0
  56. package/dist/internal/volumeLimits.d.ts.map +1 -0
  57. package/dist/internal/volumeLimits.js +63 -0
  58. package/dist/internal/volumeState.d.ts +2 -0
  59. package/dist/internal/volumeState.d.ts.map +1 -1
  60. package/dist/internal/volumeState.js +9 -0
  61. package/package.json +10 -6
@@ -1,4 +1,4 @@
1
- import * as Encoding from "effect/Encoding";
1
+ import * as Base64 from "effect/encoding/Base64";
2
2
  import * as Result from "effect/Result";
3
3
  import * as Schema from "effect/Schema";
4
4
  import { ENCODING_CHECK } from "./errors.js";
@@ -12,7 +12,7 @@ const encode = (input) => {
12
12
  const chunkBytes = 12_288;
13
13
  const chunks = [];
14
14
  for (let offset = 0; offset < input.length; offset += chunkBytes) {
15
- chunks.push(Encoding.encodeBase64(input.subarray(offset, offset + chunkBytes)));
15
+ chunks.push(Base64.encode(input.subarray(offset, offset + chunkBytes)));
16
16
  }
17
17
  return Encoded.make(chunks.join(""));
18
18
  };
@@ -23,7 +23,7 @@ const Encoded = Schema.String.pipe(Schema.refine((value) => isCanonical(value),
23
23
  /** @internal */
24
24
  export const CanonicalBase64 = {
25
25
  Encoded,
26
- toBytes: (input) => Result.getOrThrow(Encoding.decodeBase64(input)),
26
+ toBytes: (input) => Result.getOrThrow(Base64.decode(input)),
27
27
  encode: (input) => encode(input),
28
28
  decodedLength: (value) => decodedLength(value)
29
29
  };
@@ -5,7 +5,7 @@ import { Fixture as FixtureSchema, FixtureEntry } from "../Fixture.js";
5
5
  import { VolumeIdentity, VolumeOptions as VolumeOptionsSchema } from "../Volume.js";
6
6
  import { decodeConfiguration, imageFailure, OpContext, VfsError } from "./errors.js";
7
7
  import { inputBytes, isAttachedBytes, isDotComponent, preparePath } from "./path.js";
8
- import { makeVolume, VolumeSource } from "./virtualFileSystem.js";
8
+ import { makeVolume, memoryCommitProvider, VolumeSource } from "./virtualFileSystem.js";
9
9
  import { assemble, Ino, ROOT_INO } from "./volumeState.js";
10
10
  const DEFAULT_MODE = { directory: 0o755, file: 0o644, symlink: 0o777 };
11
11
  const EPOCH_NS = 0n;
@@ -124,8 +124,8 @@ export const fromFixture = Effect.fn("VirtualFileSystem.fromFixture")(function*
124
124
  const restored = VolumeSource.Restored({ value: assemble(specs) });
125
125
  const { identity, ...volumeOptions } = config;
126
126
  if (identity === undefined)
127
- return (yield* makeVolume(restored, volumeOptions)).volume;
128
- const { volume } = yield* makeVolume(restored, {
127
+ return (yield* makeVolume(restored, memoryCommitProvider, volumeOptions)).volume;
128
+ const { volume } = yield* makeVolume(restored, memoryCommitProvider, {
129
129
  ...volumeOptions,
130
130
  identity: VolumeIdentity.make(identity)
131
131
  });
@@ -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,
@@ -1,6 +1,6 @@
1
1
  import * as Arr from "effect/Array";
2
2
  import * as Data from "effect/Data";
3
- import * as Encoding from "effect/Encoding";
3
+ import * as Hex from "effect/encoding/Hex";
4
4
  import * as Order from "effect/Order";
5
5
  import * as Predicate from "effect/Predicate";
6
6
  import { bytesOrder, sameBytes } from "./bytes.js";
@@ -23,7 +23,7 @@ const tagOrder = {
23
23
  Renamed: 3,
24
24
  Updated: 4
25
25
  };
26
- const key = Encoding.encodeHex;
26
+ const key = Hex.encode;
27
27
  const sourcePath = (change) => Predicate.isTagged("Renamed")(change) ? change.from : change.path;
28
28
  const changeOrder = Order.combine(Order.mapInput(bytesOrder, sourcePath), Order.mapInput(Order.Number, (change) => tagOrder[change._tag]));
29
29
  const differences = (before, after, includeTimestamps) => Object.freeze(differenceOrder.filter((field) => {
@@ -1 +1 @@
1
- {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/internal/path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAIxD,gBAAgB;AAChB,eAAO,MAAM,SAAS,OAAO,CAAA;AAC7B,gBAAgB;AAChB,eAAO,MAAM,OAAO,OAAO,CAAA;AAC3B,gBAAgB;AAChB,eAAO,MAAM,WAAW,SAAS,CAAA;AACjC,gBAAgB;AAChB,eAAO,MAAM,UAAU,KAAK,CAAA;AAE5B,gBAAgB;AAChB,eAAO,MAAM,QAAQ,IAAI,CAAA;AACzB,gBAAgB;AAChB,eAAO,MAAM,sBAAsB,KAAK,CAAA;AACxC,gBAAgB;AAChB,eAAO,MAAM,cAAc,MAAM,CAAA;AAEjC,gBAAgB;AAChB,eAAO,MAAM,WAAW,SAAU,UAAU,KAAG,OAEuE,CAAA;AAEtH,gBAAgB;AAChB,eAAO,MAAM,SAAS,yBAA+B,CAAA;AAErD,gBAAgB;AAChB,eAAO,MAAM,QAAQ,WAAY,UAAU,QAAQ,UAAU,KAAG,UAS/D,CAAA;AAGD,gBAAgB;AAChB,eAAO,MAAM,cAAc,SAAU,MAAM,GAAG,SAAS,KAAG,IAAI,IAAI,SAAS,GAAG,OAAO,OAAO,GAAG,OAAO,WACtC,CAAA;AAEhE,gBAAgB;AAChB,eAAO,MAAM,SAAS,UAAW,UAAU,KAAG,QAA+B,CAAA;AAE7E,gBAAgB;AAChB,eAAO,MAAM,YAAY,UAAW,UAAU,aAAa,MAAM,4CAI7D,CAAA;AAEJ,gBAAgB;AAChB,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,UAAyD,CAAA;AAelG,gBAAgB;AAChB,eAAO,MAAM,eAAe,UAAW,UAAU,KAAG,OAC2C,CAAA;AAE/F,gBAAgB;AAChB,eAAO,MAAM,aAAa,mFASxB,CAAA;AAEF,gBAAgB;AAChB,eAAO,MAAM,WAAW,8EAMtB,CAAA;AAEF,gBAAgB;AAChB,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;IAC5C,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAC3C;AAGD,gBAAgB;AAChB,eAAO,MAAM,YAAY,UAAW,MAAM,KAAG,OAY5C,CAAA;AAID,gBAAgB;AAChB,eAAO,MAAM,UAAU,UAAW,SAAS,KAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,qBAAqB,GAAG,iBAAiB,CAG5B,CAAA;AAErF,gBAAgB;AAChB,eAAO,MAAM,WAAW,UACf,SAAS,aACL,MAAM,gBACH,QAAQ,CAAC,QAAQ,GAAG,SAAS,KAC1C,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAgDvC,CAAA"}
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/internal/path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAIxD,gBAAgB;AAChB,eAAO,MAAM,SAAS,OAAO,CAAA;AAC7B,gBAAgB;AAChB,eAAO,MAAM,OAAO,OAAO,CAAA;AAC3B,gBAAgB;AAChB,eAAO,MAAM,WAAW,SAAS,CAAA;AACjC,gBAAgB;AAChB,eAAO,MAAM,UAAU,KAAK,CAAA;AAE5B,gBAAgB;AAChB,eAAO,MAAM,QAAQ,IAAI,CAAA;AACzB,gBAAgB;AAChB,eAAO,MAAM,sBAAsB,KAAK,CAAA;AACxC,gBAAgB;AAChB,eAAO,MAAM,cAAc,MAAM,CAAA;AAEjC,gBAAgB;AAChB,eAAO,MAAM,WAAW,SAAU,UAAU,KAAG,OAEuE,CAAA;AAEtH,gBAAgB;AAChB,eAAO,MAAM,SAAS,yBAA+B,CAAA;AAErD,gBAAgB;AAChB,eAAO,MAAM,QAAQ,WAAY,UAAU,QAAQ,UAAU,KAAG,UAS/D,CAAA;AAGD,gBAAgB;AAChB,eAAO,MAAM,cAAc,SAAU,MAAM,GAAG,SAAS,KAAG,IAAI,IAAI,SAAS,GAAG,OAAO,OAAO,GAAG,OAAO,WACtC,CAAA;AAEhE,gBAAgB;AAChB,eAAO,MAAM,SAAS,UAAW,UAAU,KAAG,QAA+B,CAAA;AAE7E,gBAAgB;AAChB,eAAO,MAAM,YAAY,UAAW,UAAU,aAAa,MAAM,4CAI7D,CAAA;AAEJ,gBAAgB;AAChB,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,UAAiD,CAAA;AAe1F,gBAAgB;AAChB,eAAO,MAAM,eAAe,UAAW,UAAU,KAAG,OAC2C,CAAA;AAE/F,gBAAgB;AAChB,eAAO,MAAM,aAAa,mFASxB,CAAA;AAEF,gBAAgB;AAChB,eAAO,MAAM,WAAW,8EAMtB,CAAA;AAEF,gBAAgB;AAChB,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAA;IAC5C,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAC3C;AAGD,gBAAgB;AAChB,eAAO,MAAM,YAAY,UAAW,MAAM,KAAG,OAY5C,CAAA;AAID,gBAAgB;AAChB,eAAO,MAAM,UAAU,UAAW,SAAS,KAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,qBAAqB,GAAG,iBAAiB,CAG5B,CAAA;AAErF,gBAAgB;AAChB,eAAO,MAAM,WAAW,UACf,SAAS,aACL,MAAM,gBACH,QAAQ,CAAC,QAAQ,GAAG,SAAS,KAC1C,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAgDvC,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import * as ByteSize from "effect/ByteSize";
2
2
  import * as Effect from "effect/Effect";
3
- import * as Encoding from "effect/Encoding";
3
+ import * as Hex from "effect/encoding/Hex";
4
4
  import * as Predicate from "effect/Predicate";
5
5
  import * as Result from "effect/Result";
6
6
  import { getBytes as getBytePathBytes, make as makeBytePath } from "./bytePath.js";
@@ -46,7 +46,7 @@ export const strictString = (bytes, operation) => Effect.try({
46
46
  catch: () => fsFailure("UnrepresentableName", operation)
47
47
  });
48
48
  /** @internal */
49
- export const nameBytes = (name) => Result.getOrThrow(Encoding.decodeHex(name));
49
+ export const nameBytes = (name) => Result.getOrThrow(Hex.decode(name));
50
50
  // Constructing a view detects detached buffers, including empty ones.
51
51
  const attachedBuffer = (bytes) => {
52
52
  try {
@@ -125,7 +125,7 @@ export const preparePath = (input, operation, maxPathBytes) => {
125
125
  if (index - start > MAX_NAME_BYTES) {
126
126
  return Result.fail(fsFailure("PathTooLong", operation, { path: input }));
127
127
  }
128
- components.push(Encoding.encodeHex(bytes.subarray(start, index)));
128
+ components.push(Hex.encode(bytes.subarray(start, index)));
129
129
  suffixes.push(bytes.subarray(index));
130
130
  }
131
131
  start = index + 1;