@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.
- package/README.md +15 -238
- package/dist/LiveVolume.d.ts.map +1 -1
- package/dist/LiveVolume.js +9 -9
- package/dist/Search.d.ts +730 -0
- package/dist/Search.d.ts.map +1 -0
- package/dist/Search.js +568 -0
- package/dist/SnapshotDelta.d.ts +234 -0
- package/dist/SnapshotDelta.d.ts.map +1 -1
- package/dist/SnapshotDelta.js +107 -0
- package/dist/VirtualFileSystem.d.ts +53 -1
- package/dist/VirtualFileSystem.d.ts.map +1 -1
- package/dist/VirtualFileSystem.js +59 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/internal/canonicalBase64.js +3 -3
- package/dist/internal/fixture.js +3 -3
- package/dist/internal/glob.d.ts +66 -0
- package/dist/internal/glob.d.ts.map +1 -0
- package/dist/internal/glob.js +248 -0
- package/dist/internal/image.d.ts +7 -1
- package/dist/internal/image.d.ts.map +1 -1
- package/dist/internal/image.js +9 -7
- package/dist/internal/liveImage.d.ts +1 -1
- package/dist/internal/liveImage.d.ts.map +1 -1
- package/dist/internal/liveImage.js +2 -10
- package/dist/internal/overlayDiff.js +2 -2
- package/dist/internal/path.d.ts.map +1 -1
- package/dist/internal/path.js +3 -3
- package/dist/internal/resolution.d.ts +135 -0
- package/dist/internal/resolution.d.ts.map +1 -0
- package/dist/internal/resolution.js +277 -0
- package/dist/internal/search.d.ts +24 -0
- package/dist/internal/search.d.ts.map +1 -0
- package/dist/internal/search.js +78 -0
- package/dist/internal/searchContent.d.ts +77 -0
- package/dist/internal/searchContent.d.ts.map +1 -0
- package/dist/internal/searchContent.js +223 -0
- package/dist/internal/searchModel.d.ts +83 -0
- package/dist/internal/searchModel.d.ts.map +1 -0
- package/dist/internal/searchModel.js +23 -0
- package/dist/internal/snapshotDelta.d.ts +470 -1
- package/dist/internal/snapshotDelta.d.ts.map +1 -1
- package/dist/internal/snapshotDelta.js +60 -26
- package/dist/internal/snapshotMerge.d.ts +54 -0
- package/dist/internal/snapshotMerge.d.ts.map +1 -0
- package/dist/internal/snapshotMerge.js +959 -0
- package/dist/internal/tokenRegistry.d.ts +77 -0
- package/dist/internal/tokenRegistry.d.ts.map +1 -0
- package/dist/internal/tokenRegistry.js +128 -0
- package/dist/internal/tree.js +2 -2
- package/dist/internal/virtualFileSystem.d.ts +32 -17
- package/dist/internal/virtualFileSystem.d.ts.map +1 -1
- package/dist/internal/virtualFileSystem.js +640 -993
- package/dist/internal/volumeLimits.d.ts +53 -0
- package/dist/internal/volumeLimits.d.ts.map +1 -0
- package/dist/internal/volumeLimits.js +63 -0
- package/dist/internal/volumeState.d.ts +2 -0
- package/dist/internal/volumeState.d.ts.map +1 -1
- package/dist/internal/volumeState.js +9 -0
- package/package.json +10 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
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(
|
|
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(
|
|
26
|
+
toBytes: (input) => Result.getOrThrow(Base64.decode(input)),
|
|
27
27
|
encode: (input) => encode(input),
|
|
28
28
|
decodedLength: (value) => decodedLength(value)
|
|
29
29
|
};
|
package/dist/internal/fixture.js
CHANGED
|
@@ -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
|
+
});
|
package/dist/internal/image.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/internal/image.js
CHANGED
|
@@ -64,10 +64,11 @@ export const decodeSnapshotSink = (budget) => {
|
|
|
64
64
|
};
|
|
65
65
|
const OPERATION = "snapshotEntries";
|
|
66
66
|
const encoder = new TextEncoder();
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const
|
|
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" ||
|
|
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),
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"liveImage.d.ts","sourceRoot":"","sources":["../../src/internal/liveImage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,QAAQ,MAAM,iBAAiB,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
|
|
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 =
|
|
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,
|
|
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"}
|
package/dist/internal/path.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as ByteSize from "effect/ByteSize";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
|
-
import * as
|
|
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(
|
|
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(
|
|
128
|
+
components.push(Hex.encode(bytes.subarray(start, index)));
|
|
129
129
|
suffixes.push(bytes.subarray(index));
|
|
130
130
|
}
|
|
131
131
|
start = index + 1;
|