@effect-vfs/core 0.2.0 → 0.3.1

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 (67) hide show
  1. package/dist/BytePath.d.ts +49 -5
  2. package/dist/BytePath.d.ts.map +1 -1
  3. package/dist/BytePath.js +9 -9
  4. package/dist/Snapshot.d.ts +61 -5
  5. package/dist/Snapshot.d.ts.map +1 -1
  6. package/dist/Snapshot.js +60 -5
  7. package/dist/SnapshotDelta.d.ts +208 -31
  8. package/dist/SnapshotDelta.d.ts.map +1 -1
  9. package/dist/SnapshotDelta.js +162 -25
  10. package/dist/VirtualFileSystem.d.ts +1035 -348
  11. package/dist/VirtualFileSystem.d.ts.map +1 -1
  12. package/dist/VirtualFileSystem.js +620 -1772
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +1 -1
  15. package/dist/internal/bytePath.d.ts +10 -0
  16. package/dist/internal/bytePath.d.ts.map +1 -0
  17. package/dist/internal/bytePath.js +41 -0
  18. package/dist/internal/bytes.d.ts +6 -0
  19. package/dist/internal/bytes.d.ts.map +1 -0
  20. package/dist/internal/bytes.js +17 -0
  21. package/dist/internal/canonicalBase64.d.ts +14 -6
  22. package/dist/internal/canonicalBase64.d.ts.map +1 -1
  23. package/dist/internal/canonicalBase64.js +29 -7
  24. package/dist/internal/image.d.ts +85 -104
  25. package/dist/internal/image.d.ts.map +1 -1
  26. package/dist/internal/image.js +99 -95
  27. package/dist/internal/metadata.d.ts +28 -0
  28. package/dist/internal/metadata.d.ts.map +1 -0
  29. package/dist/internal/metadata.js +29 -0
  30. package/dist/internal/snapshotDelta.d.ts +0 -1
  31. package/dist/internal/snapshotDelta.d.ts.map +1 -1
  32. package/dist/internal/snapshotDelta.js +358 -325
  33. package/dist/internal/snapshotDeltaModel.d.ts +10 -0
  34. package/dist/internal/snapshotDeltaModel.d.ts.map +1 -0
  35. package/dist/internal/snapshotDeltaModel.js +15 -0
  36. package/dist/internal/virtualFileSystem/errors.d.ts +31 -0
  37. package/dist/internal/virtualFileSystem/errors.d.ts.map +1 -0
  38. package/dist/internal/virtualFileSystem/errors.js +51 -0
  39. package/dist/internal/virtualFileSystem/fixture.d.ts +63 -0
  40. package/dist/internal/virtualFileSystem/fixture.d.ts.map +1 -0
  41. package/dist/internal/virtualFileSystem/fixture.js +144 -0
  42. package/dist/internal/{content.d.ts → virtualFileSystem/overlayContent.d.ts} +4 -14
  43. package/dist/internal/virtualFileSystem/overlayContent.d.ts.map +1 -0
  44. package/dist/internal/virtualFileSystem/overlayContent.js +29 -0
  45. package/dist/internal/{overlayChanges.d.ts → virtualFileSystem/overlayDiff.d.ts} +3 -12
  46. package/dist/internal/virtualFileSystem/overlayDiff.d.ts.map +1 -0
  47. package/dist/internal/virtualFileSystem/overlayDiff.js +120 -0
  48. package/dist/internal/virtualFileSystem/path.d.ts +44 -0
  49. package/dist/internal/virtualFileSystem/path.d.ts.map +1 -0
  50. package/dist/internal/virtualFileSystem/path.js +127 -0
  51. package/dist/internal/virtualFileSystem/testHooks.d.ts +20 -0
  52. package/dist/internal/virtualFileSystem/testHooks.d.ts.map +1 -0
  53. package/dist/internal/virtualFileSystem/testHooks.js +23 -0
  54. package/dist/internal/virtualFileSystem/watchHub.d.ts +16 -0
  55. package/dist/internal/virtualFileSystem/watchHub.d.ts.map +1 -0
  56. package/dist/internal/virtualFileSystem/watchHub.js +33 -0
  57. package/dist/internal/virtualFileSystem.d.ts +366 -0
  58. package/dist/internal/virtualFileSystem.d.ts.map +1 -0
  59. package/dist/internal/virtualFileSystem.js +1755 -0
  60. package/package.json +15 -5
  61. package/dist/internal/content.d.ts.map +0 -1
  62. package/dist/internal/content.js +0 -26
  63. package/dist/internal/overlayChanges.d.ts.map +0 -1
  64. package/dist/internal/overlayChanges.js +0 -146
  65. package/dist/internal/overlayTesting.d.ts +0 -12
  66. package/dist/internal/overlayTesting.d.ts.map +0 -1
  67. package/dist/internal/overlayTesting.js +0 -12
@@ -1,13 +1,59 @@
1
+ /**
2
+ * Opaque, byte-preserving filesystem paths.
3
+ *
4
+ * A `BytePath` stores the exact bytes of a path component so that names which
5
+ * are not valid UTF-8 survive a round trip through the virtual filesystem.
6
+ *
7
+ * @since 0.1.0
8
+ */
9
+ import type * as Equal from "effect/Equal";
10
+ import type { Pipeable } from "effect/Pipeable";
1
11
  import * as Schema from "effect/Schema";
2
- export declare const BytePathId: unique symbol;
12
+ /**
13
+ * Type identifier for opaque byte-preserving filesystem paths.
14
+ *
15
+ * @category type IDs
16
+ * @since 0.1.0
17
+ */
18
+ export declare const BytePathId: "@effect-vfs/core/BytePath";
19
+ /**
20
+ * Type identifier for opaque byte-preserving filesystem paths.
21
+ *
22
+ * @category type IDs
23
+ * @since 0.1.0
24
+ */
25
+ export type BytePathId = typeof BytePathId;
3
26
  /**
4
27
  * An opaque path that preserves arbitrary non-NUL bytes without UTF-8 conversion.
5
28
  *
29
+ * @example
30
+ * ```ts
31
+ * import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
32
+ * import { Effect } from "effect"
33
+ *
34
+ * // A name that is not valid UTF-8 still round-trips exactly.
35
+ * const program = Effect.gen(function*() {
36
+ * const caller = yield* (yield* Vfs.make()).caller()
37
+ * const path = yield* Vfs.pathFromBytes(new Uint8Array([47, 0xff, 0xfe]))
38
+ *
39
+ * yield* caller.writeFile(path, new Uint8Array([1]), {
40
+ * access: "write",
41
+ * create: "exclusive"
42
+ * })
43
+ *
44
+ * // `readDirectory` fails `UnrepresentableName` here; the byte variant keeps it.
45
+ * return yield* caller.readDirectoryBytes("/")
46
+ * })
47
+ *
48
+ * Effect.runPromise(program).then(console.log)
49
+ * // [ Uint8Array(2) [ 255, 254 ] ]
50
+ * ```
51
+ *
6
52
  * @category models
7
53
  * @since 0.1.0
8
54
  */
9
- export interface BytePath {
10
- readonly [BytePathId]: true;
55
+ export interface BytePath extends Equal.Equal, Pipeable {
56
+ readonly [BytePathId]: BytePathId;
11
57
  }
12
58
  /**
13
59
  * Schema for an opaque byte-preserving filesystem path.
@@ -16,6 +62,4 @@ export interface BytePath {
16
62
  * @since 0.1.0
17
63
  */
18
64
  export declare const BytePath: Schema.declare<BytePath, BytePath>;
19
- export declare const make: (bytes: Uint8Array) => BytePath;
20
- export declare const getBytes: (path: BytePath) => Uint8Array | undefined;
21
65
  //# sourceMappingURL=BytePath.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BytePath.d.ts","sourceRoot":"","sources":["../src/BytePath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,eAAO,MAAM,UAAU,eAAsC,CAAA;AAI7D;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,CAAA;CAC5B;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,oCAEpB,CAAA;AAED,eAAO,MAAM,IAAI,UAAW,UAAU,KAAG,QAIxC,CAAA;AAED,eAAO,MAAM,QAAQ,SAAU,QAAQ,KAAG,UAAU,GAAG,SAAgC,CAAA"}
1
+ {"version":3,"file":"BytePath.d.ts","sourceRoot":"","sources":["../src/BytePath.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE,2BAAiD,CAAA;AAE1E;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAA;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,WAAW,QAAS,SAAQ,KAAK,CAAC,KAAK,EAAE,QAAQ;IACrD,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,UAAU,CAAA;CAClC;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,oCAAgD,CAAA"}
package/dist/BytePath.js CHANGED
@@ -1,16 +1,16 @@
1
1
  import * as Schema from "effect/Schema";
2
- export const BytePathId = Symbol("@effect-vfs/core/BytePath");
3
- const bytePaths = new WeakMap();
2
+ import * as Internal from "./internal/bytePath.js";
3
+ /**
4
+ * Type identifier for opaque byte-preserving filesystem paths.
5
+ *
6
+ * @category type IDs
7
+ * @since 0.1.0
8
+ */
9
+ export const BytePathId = Internal.BytePathId;
4
10
  /**
5
11
  * Schema for an opaque byte-preserving filesystem path.
6
12
  *
7
13
  * @category schemas
8
14
  * @since 0.1.0
9
15
  */
10
- export const BytePath = Schema.declare((value) => typeof value === "object" && value !== null && bytePaths.has(value));
11
- export const make = (bytes) => {
12
- const path = Object.freeze({ [BytePathId]: true });
13
- bytePaths.set(path, bytes);
14
- return path;
15
- };
16
- export const getBytes = (path) => bytePaths.get(path);
16
+ export const BytePath = Schema.declare(Internal.isBytePath);
@@ -2,14 +2,14 @@ import * as Schema from "effect/Schema";
2
2
  /**
3
3
  * Type identifier for opaque filesystem snapshots.
4
4
  *
5
- * @category type ids
5
+ * @category type IDs
6
6
  * @since 0.1.0
7
7
  */
8
- export declare const SnapshotTypeId: unique symbol;
8
+ export declare const SnapshotTypeId: "@effect-vfs/core/Snapshot";
9
9
  /**
10
10
  * Type identifier for opaque filesystem snapshots.
11
11
  *
12
- * @category type ids
12
+ * @category type IDs
13
13
  * @since 0.1.0
14
14
  */
15
15
  export type SnapshotTypeId = typeof SnapshotTypeId;
@@ -28,6 +28,35 @@ declare const ImageError_base: new <A extends Record<string, any> = {}>(args: im
28
28
  /**
29
29
  * Describes a snapshot encoding, decoding, structure, or resource-limit failure.
30
30
  *
31
+ * @example
32
+ * ```ts
33
+ * import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
34
+ * import { ByteSize, Effect } from "effect"
35
+ *
36
+ * // Decoding is a trust boundary. `code` says what went wrong and `field` says
37
+ * // which input or limit it was, so a caller can decline just the bad payload.
38
+ * const program = Effect.gen(function*() {
39
+ * const volume = yield* Vfs.make()
40
+ * const bytes = yield* Vfs.encodeSnapshot(yield* volume.snapshot)
41
+ *
42
+ * return yield* Vfs.decodeSnapshot(bytes, {
43
+ * maxEncodedBytes: ByteSize.bytes(16),
44
+ * maxRecords: 10_000,
45
+ * maxEntries: 10_000,
46
+ * maxDecodedBytes: ByteSize.megabytes(16)
47
+ * }).pipe(
48
+ * Effect.as("accepted"),
49
+ * Effect.catchTag("ImageError", (error) =>
50
+ * error.code === "LimitExceeded"
51
+ * ? Effect.succeed(`declined at ${error.field}`)
52
+ * : Effect.fail(error))
53
+ * )
54
+ * })
55
+ *
56
+ * Effect.runPromise(program).then(console.log)
57
+ * // declined at encodedBytes
58
+ * ```
59
+ *
31
60
  * @category errors
32
61
  * @since 0.1.0
33
62
  */
@@ -41,6 +70,33 @@ export declare class ImageError extends ImageError_base<{
41
70
  /**
42
71
  * Schema for the mandatory resource limits applied while decoding a snapshot.
43
72
  *
73
+ * @example
74
+ * ```ts
75
+ * import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
76
+ * import { ByteSize, Effect } from "effect"
77
+ *
78
+ * // All four are required: each bounds a different resource. `maxEncodedBytes`
79
+ * // caps the wire payload before parsing; `maxDecodedBytes` caps memory after it.
80
+ * const limits: Vfs.DecodeLimits = {
81
+ * maxEncodedBytes: ByteSize.megabytes(4),
82
+ * maxRecords: 10_000,
83
+ * maxEntries: 10_000,
84
+ * maxDecodedBytes: ByteSize.megabytes(16)
85
+ * }
86
+ *
87
+ * const program = Effect.gen(function*() {
88
+ * const volume = yield* Vfs.make()
89
+ * const bytes = yield* Vfs.encodeSnapshot(yield* volume.snapshot)
90
+ *
91
+ * yield* Vfs.decodeSnapshot(bytes, limits)
92
+ *
93
+ * return "accepted"
94
+ * })
95
+ *
96
+ * Effect.runPromise(program).then(console.log)
97
+ * // accepted
98
+ * ```
99
+ *
44
100
  * @category schemas
45
101
  * @since 0.1.0
46
102
  */
@@ -48,9 +104,9 @@ export declare const DecodeLimits: Schema.Struct<{
48
104
  /** Maximum accepted encoded input length in bytes. */
49
105
  readonly maxEncodedBytes: Schema.ByteSize;
50
106
  /** Maximum number of stored metadata and content records. */
51
- readonly maxRecords: Schema.Finite;
107
+ readonly maxRecords: Schema.Natural;
52
108
  /** Maximum number of namespace entries. */
53
- readonly maxEntries: Schema.Finite;
109
+ readonly maxEntries: Schema.Natural;
54
110
  /** Maximum combined decoded byte content. */
55
111
  readonly maxDecodedBytes: Schema.ByteSize;
56
112
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"Snapshot.d.ts","sourceRoot":"","sources":["../src/Snapshot.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAQvC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,eAAsC,CAAA;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAA;AAElD;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAE,cAAc,CAAA;CAC1C;;;;AAED;;;;;GAKG;AACH,qBAAa,UAAW,SAAQ,gBAA+B;IAC7D,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,eAAe,CAAA;IAC9F,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB,CAAC;CAAG;AAEL;;;;;GAKG;AACH,eAAO,MAAM,YAAY;IACvB,sDAAsD;;IAEtD,6DAA6D;;IAE7D,2CAA2C;;IAE3C,6CAA6C;;EAE7C,CAAA;AAEF;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA"}
1
+ {"version":3,"file":"Snapshot.d.ts","sourceRoot":"","sources":["../src/Snapshot.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAG,2BAAoC,CAAA;AAElE;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAA;AAElD;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAE,cAAc,CAAA;CAC1C;;;;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,UAAW,SAAQ,gBAA+B;IAC7D,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,eAAe,CAAA;IAC9F,kFAAkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB,CAAC;CAAG;AAEL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,YAAY;IACvB,sDAAsD;;IAEtD,6DAA6D;;IAE7D,2CAA2C;;IAE3C,6CAA6C;;EAE7C,CAAA;AAEF;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA"}
package/dist/Snapshot.js CHANGED
@@ -9,17 +9,45 @@
9
9
  */
10
10
  import * as Data from "effect/Data";
11
11
  import * as Schema from "effect/Schema";
12
- const Natural = Schema.Finite.check(Schema.isInt(), Schema.isGreaterThanOrEqualTo(0), Schema.isLessThanOrEqualTo(Number.MAX_SAFE_INTEGER));
13
12
  /**
14
13
  * Type identifier for opaque filesystem snapshots.
15
14
  *
16
- * @category type ids
15
+ * @category type IDs
17
16
  * @since 0.1.0
18
17
  */
19
- export const SnapshotTypeId = Symbol("@effect-vfs/core/Snapshot");
18
+ export const SnapshotTypeId = "@effect-vfs/core/Snapshot";
20
19
  /**
21
20
  * Describes a snapshot encoding, decoding, structure, or resource-limit failure.
22
21
  *
22
+ * @example
23
+ * ```ts
24
+ * import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
25
+ * import { ByteSize, Effect } from "effect"
26
+ *
27
+ * // Decoding is a trust boundary. `code` says what went wrong and `field` says
28
+ * // which input or limit it was, so a caller can decline just the bad payload.
29
+ * const program = Effect.gen(function*() {
30
+ * const volume = yield* Vfs.make()
31
+ * const bytes = yield* Vfs.encodeSnapshot(yield* volume.snapshot)
32
+ *
33
+ * return yield* Vfs.decodeSnapshot(bytes, {
34
+ * maxEncodedBytes: ByteSize.bytes(16),
35
+ * maxRecords: 10_000,
36
+ * maxEntries: 10_000,
37
+ * maxDecodedBytes: ByteSize.megabytes(16)
38
+ * }).pipe(
39
+ * Effect.as("accepted"),
40
+ * Effect.catchTag("ImageError", (error) =>
41
+ * error.code === "LimitExceeded"
42
+ * ? Effect.succeed(`declined at ${error.field}`)
43
+ * : Effect.fail(error))
44
+ * )
45
+ * })
46
+ *
47
+ * Effect.runPromise(program).then(console.log)
48
+ * // declined at encodedBytes
49
+ * ```
50
+ *
23
51
  * @category errors
24
52
  * @since 0.1.0
25
53
  */
@@ -28,6 +56,33 @@ export class ImageError extends Data.TaggedError("ImageError") {
28
56
  /**
29
57
  * Schema for the mandatory resource limits applied while decoding a snapshot.
30
58
  *
59
+ * @example
60
+ * ```ts
61
+ * import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
62
+ * import { ByteSize, Effect } from "effect"
63
+ *
64
+ * // All four are required: each bounds a different resource. `maxEncodedBytes`
65
+ * // caps the wire payload before parsing; `maxDecodedBytes` caps memory after it.
66
+ * const limits: Vfs.DecodeLimits = {
67
+ * maxEncodedBytes: ByteSize.megabytes(4),
68
+ * maxRecords: 10_000,
69
+ * maxEntries: 10_000,
70
+ * maxDecodedBytes: ByteSize.megabytes(16)
71
+ * }
72
+ *
73
+ * const program = Effect.gen(function*() {
74
+ * const volume = yield* Vfs.make()
75
+ * const bytes = yield* Vfs.encodeSnapshot(yield* volume.snapshot)
76
+ *
77
+ * yield* Vfs.decodeSnapshot(bytes, limits)
78
+ *
79
+ * return "accepted"
80
+ * })
81
+ *
82
+ * Effect.runPromise(program).then(console.log)
83
+ * // accepted
84
+ * ```
85
+ *
31
86
  * @category schemas
32
87
  * @since 0.1.0
33
88
  */
@@ -35,9 +90,9 @@ export const DecodeLimits = Schema.Struct({
35
90
  /** Maximum accepted encoded input length in bytes. */
36
91
  maxEncodedBytes: Schema.ByteSize,
37
92
  /** Maximum number of stored metadata and content records. */
38
- maxRecords: Natural,
93
+ maxRecords: Schema.Natural,
39
94
  /** Maximum number of namespace entries. */
40
- maxEntries: Natural,
95
+ maxEntries: Schema.Natural,
41
96
  /** Maximum combined decoded byte content. */
42
97
  maxDecodedBytes: Schema.ByteSize
43
98
  });
@@ -6,33 +6,105 @@
6
6
  import * as ByteSize from "effect/ByteSize";
7
7
  import * as Schema from "effect/Schema";
8
8
  import { BytePath } from "./BytePath.js";
9
- /** Type identifier for opaque snapshot deltas. */
10
- export declare const SnapshotDeltaTypeId: unique symbol;
11
- /** Type identifier for opaque snapshot deltas. */
9
+ /**
10
+ * Type identifier for opaque snapshot deltas.
11
+ *
12
+ * @category type IDs
13
+ * @since 0.1.0
14
+ */
15
+ export declare const SnapshotDeltaTypeId: "@effect-vfs/core/SnapshotDelta";
16
+ /**
17
+ * Type identifier for opaque snapshot deltas.
18
+ *
19
+ * @category type IDs
20
+ * @since 0.1.0
21
+ */
12
22
  export type SnapshotDeltaTypeId = typeof SnapshotDeltaTypeId;
13
- /** An immutable, opaque description of the exact difference between two snapshots. */
23
+ /**
24
+ * An immutable, opaque description of the exact difference between two snapshots.
25
+ *
26
+ * @category models
27
+ * @since 0.1.0
28
+ */
14
29
  export interface SnapshotDelta {
15
30
  readonly [SnapshotDeltaTypeId]: SnapshotDeltaTypeId;
16
31
  }
17
- /** @internal */
18
- export declare const makeSnapshotDelta: (value: object) => SnapshotDelta;
19
- /** @internal */
20
- export declare const snapshotDeltaValue: (delta: SnapshotDelta) => object | undefined;
21
- /** Schema for an already validated opaque snapshot delta. */
32
+ /**
33
+ * Schema for an already validated opaque snapshot delta.
34
+ *
35
+ * @category schemas
36
+ * @since 0.1.0
37
+ */
22
38
  export declare const SnapshotDelta: Schema.declare<SnapshotDelta, SnapshotDelta>;
23
- /** Schema for filesystem entry kinds reported by snapshot inspection. */
39
+ /**
40
+ * Schema for filesystem entry kinds reported by snapshot inspection.
41
+ *
42
+ * @category schemas
43
+ * @since 0.1.0
44
+ */
24
45
  export declare const SnapshotNodeKind: Schema.Literals<readonly ["directory", "file", "symlink"]>;
25
- /** A filesystem entry kind reported by snapshot inspection. */
46
+ /**
47
+ * A filesystem entry kind reported by snapshot inspection.
48
+ *
49
+ * @category models
50
+ * @since 0.1.0
51
+ */
26
52
  export type SnapshotNodeKind = typeof SnapshotNodeKind.Type;
27
- /** Schema for semantic fields that can differ between snapshots. */
53
+ /**
54
+ * Schema for semantic fields that can differ between snapshots.
55
+ *
56
+ * @category schemas
57
+ * @since 0.1.0
58
+ */
28
59
  export declare const SnapshotDifference: Schema.Literals<readonly ["kind", "content", "target", "hardLinks", "mode", "uid", "gid", "atimeNs", "mtimeNs", "ctimeNs", "birthtimeNs"]>;
29
- /** A semantic field that differs between two snapshots. */
60
+ /**
61
+ * A semantic field that differs between two snapshots.
62
+ *
63
+ * @category models
64
+ * @since 0.1.0
65
+ */
30
66
  export type SnapshotDifference = typeof SnapshotDifference.Type;
31
67
  /**
32
68
  * Schema for a path-oriented difference between two snapshots.
33
69
  *
34
70
  * Independent snapshots do not preserve shared lineage, so moves are reported
35
71
  * as a removal and an addition rather than an inferred rename.
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
76
+ * import * as NodeCrypto from "@effect/platform-node-shared/NodeCrypto"
77
+ * import { Effect } from "effect"
78
+ *
79
+ * const program = Effect.gen(function*() {
80
+ * const volume = yield* Vfs.make()
81
+ * const caller = yield* volume.caller()
82
+ *
83
+ * yield* caller.writeFile("/f", new Uint8Array([1]), {
84
+ * access: "write",
85
+ * create: "exclusive"
86
+ * })
87
+ *
88
+ * const base = yield* volume.snapshot
89
+ *
90
+ * yield* caller.writeFile("/f", new Uint8Array([2, 3]), { access: "write", truncate: true })
91
+ * yield* caller.chmod("/f", 0o600)
92
+ *
93
+ * const delta = yield* Vfs.diffSnapshots(base, yield* volume.snapshot)
94
+ * const changes = yield* Vfs.inspectSnapshotDelta(base, delta)
95
+ *
96
+ * // `Updated` carries which fields moved; `Added` and `Removed` carry a kind.
97
+ * const change = changes[0]!
98
+ *
99
+ * return change._tag === "Updated" ? change.differences : change.kind
100
+ * }).pipe(Effect.provide(NodeCrypto.layer))
101
+ *
102
+ * Effect.runPromise(program).then(console.log)
103
+ * // [ 'content', 'mode' ]
104
+ * ```
105
+ *
106
+ * @category schemas
107
+ * @since 0.1.0
36
108
  */
37
109
  export declare const SnapshotChange: Schema.Union<readonly [Schema.TaggedStruct<"Added", {
38
110
  readonly path: Schema.declare<BytePath, BytePath>;
@@ -46,19 +118,91 @@ export declare const SnapshotChange: Schema.Union<readonly [Schema.TaggedStruct<
46
118
  readonly afterKind: Schema.Literals<readonly ["directory", "file", "symlink"]>;
47
119
  readonly differences: Schema.$Array<Schema.Literals<readonly ["kind", "content", "target", "hardLinks", "mode", "uid", "gid", "atimeNs", "mtimeNs", "ctimeNs", "birthtimeNs"]>>;
48
120
  }>]>;
49
- /** A path-oriented semantic difference between two snapshots. */
121
+ /**
122
+ * A path-oriented semantic difference between two snapshots.
123
+ *
124
+ * @category models
125
+ * @since 0.1.0
126
+ */
50
127
  export type SnapshotChange = typeof SnapshotChange.Type;
51
- /** Schema for snapshot-delta inspection options. */
128
+ /**
129
+ * Schema for snapshot-delta inspection options.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
134
+ * import * as NodeCrypto from "@effect/platform-node-shared/NodeCrypto"
135
+ * import { Effect } from "effect"
136
+ *
137
+ * const program = Effect.gen(function*() {
138
+ * const volume = yield* Vfs.make()
139
+ * const caller = yield* volume.caller()
140
+ * const base = yield* volume.snapshot
141
+ *
142
+ * yield* caller.mkdir("/work")
143
+ *
144
+ * const delta = yield* Vfs.diffSnapshots(base, yield* volume.snapshot)
145
+ *
146
+ * // Timestamps are excluded by default, since they change on every write.
147
+ * const plain = yield* Vfs.inspectSnapshotDelta(base, delta)
148
+ * const timed = yield* Vfs.inspectSnapshotDelta(base, delta, { includeTimestamps: true })
149
+ *
150
+ * return [plain.length, timed.length]
151
+ * }).pipe(Effect.provide(NodeCrypto.layer))
152
+ *
153
+ * Effect.runPromise(program).then(console.log)
154
+ * // [ 1, 2 ]
155
+ * ```
156
+ *
157
+ * @category schemas
158
+ * @since 0.1.0
159
+ */
52
160
  export declare const SnapshotChangesOptions: Schema.Struct<{
53
161
  /** Include access, modification, change, and birth-time differences. Defaults to `false`. */
54
162
  readonly includeTimestamps: Schema.optionalKey<Schema.Boolean>;
55
163
  }>;
56
- /** Filtering options for snapshot-delta inspection. */
164
+ /**
165
+ * Filtering options for snapshot-delta inspection.
166
+ *
167
+ * @category models
168
+ * @since 0.1.0
169
+ */
57
170
  export type SnapshotChangesOptions = typeof SnapshotChangesOptions.Type;
58
171
  declare const SnapshotDeltaError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
59
172
  readonly _tag: "SnapshotDeltaError";
60
173
  } & Readonly<A>;
61
- /** A valid snapshot delta was inspected or applied against a valid but semantically different base. */
174
+ /**
175
+ * A valid snapshot delta was inspected or applied against a valid but semantically different base.
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
180
+ * import * as NodeCrypto from "@effect/platform-node-shared/NodeCrypto"
181
+ * import { Effect } from "effect"
182
+ *
183
+ * const program = Effect.gen(function*() {
184
+ * const volume = yield* Vfs.make()
185
+ * const caller = yield* volume.caller()
186
+ * const base = yield* volume.snapshot
187
+ *
188
+ * yield* caller.mkdir("/work")
189
+ *
190
+ * // Omitting limits uses `default`; `constrained` suits memory-sensitive hosts.
191
+ * const tight = { ...Vfs.SnapshotDeltaLimits.constrained, maxOutputRecords: 0 }
192
+ *
193
+ * return yield* Vfs.diffSnapshots(base, yield* volume.snapshot, tight).pipe(
194
+ * Effect.as("diffed"),
195
+ * Effect.catchTag("ImageError", (error) => Effect.succeed(`${error.code} at ${error.field}`))
196
+ * )
197
+ * }).pipe(Effect.provide(NodeCrypto.layer))
198
+ *
199
+ * Effect.runPromise(program).then(console.log)
200
+ * // LimitExceeded at outputRecords
201
+ * ```
202
+ *
203
+ * @category errors
204
+ * @since 0.1.0
205
+ */
62
206
  export declare class SnapshotDeltaError extends SnapshotDeltaError_base<{
63
207
  readonly code: "BaseMismatch";
64
208
  }> {
@@ -66,36 +210,69 @@ export declare class SnapshotDeltaError extends SnapshotDeltaError_base<{
66
210
  declare const SnapshotDeltaLimitsSchema: Schema.Struct<{
67
211
  readonly maxEncodedBytes: Schema.ByteSize;
68
212
  readonly maxIdentityBytes: Schema.ByteSize;
69
- readonly maxDeltaRecords: Schema.Finite;
213
+ readonly maxDeltaRecords: Schema.Natural;
70
214
  readonly maxDecodedDeltaBytes: Schema.ByteSize;
71
- readonly maxBaseRecords: Schema.Finite;
72
- readonly maxTargetRecords: Schema.Finite;
73
- readonly maxEntries: Schema.Finite;
74
- readonly maxOutputRecords: Schema.Finite;
215
+ readonly maxBaseRecords: Schema.Natural;
216
+ readonly maxTargetRecords: Schema.Natural;
217
+ readonly maxEntries: Schema.Natural;
218
+ readonly maxOutputRecords: Schema.Natural;
75
219
  readonly maxOutputBytes: Schema.ByteSize;
76
- readonly maxInheritedRecords: Schema.Finite;
220
+ readonly maxInheritedRecords: Schema.Natural;
77
221
  }>;
78
- /** Resource limits shared by delta creation, inspection, encoding, decoding, and application. */
222
+ /**
223
+ * Resource limits shared by delta creation, inspection, encoding, decoding, and application.
224
+ *
225
+ * @category models
226
+ * @since 0.1.0
227
+ */
79
228
  export type SnapshotDeltaLimits = typeof SnapshotDeltaLimitsSchema.Type;
80
- /** Constructs and freezes a complete snapshot-delta resource policy. @internal */
229
+ /**
230
+ * Constructs and freezes a complete snapshot-delta resource policy.
231
+ *
232
+ * @internal
233
+ */
81
234
  export declare const makeSnapshotDeltaLimits: (limits: SnapshotDeltaLimits) => SnapshotDeltaLimits;
82
235
  /**
83
236
  * Schema for a complete snapshot-delta resource policy, with frozen presets.
84
237
  *
85
238
  * The constrained preset is intended for memory-sensitive environments. The
86
239
  * default preset permits larger snapshots and payloads while remaining finite.
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * import { VirtualFileSystem as Vfs } from "@effect-vfs/core"
244
+ * import * as NodeCrypto from "@effect/platform-node-shared/NodeCrypto"
245
+ * import { Effect } from "effect"
246
+ *
247
+ * const program = Effect.gen(function*() {
248
+ * const volume = yield* Vfs.make()
249
+ * const base = yield* volume.snapshot
250
+ *
251
+ * yield* (yield* volume.caller()).mkdir("/work")
252
+ *
253
+ * // Omitting limits uses `default`; pass `constrained` where memory is tight.
254
+ * return yield* Vfs.diffSnapshots(
255
+ * base,
256
+ * yield* volume.snapshot,
257
+ * Vfs.SnapshotDeltaLimits.constrained
258
+ * )
259
+ * }).pipe(Effect.provide(NodeCrypto.layer))
260
+ * ```
261
+ *
262
+ * @category schemas
263
+ * @since 0.1.0
87
264
  */
88
265
  export declare const SnapshotDeltaLimits: Schema.Struct<{
89
266
  readonly maxEncodedBytes: Schema.ByteSize;
90
267
  readonly maxIdentityBytes: Schema.ByteSize;
91
- readonly maxDeltaRecords: Schema.Finite;
268
+ readonly maxDeltaRecords: Schema.Natural;
92
269
  readonly maxDecodedDeltaBytes: Schema.ByteSize;
93
- readonly maxBaseRecords: Schema.Finite;
94
- readonly maxTargetRecords: Schema.Finite;
95
- readonly maxEntries: Schema.Finite;
96
- readonly maxOutputRecords: Schema.Finite;
270
+ readonly maxBaseRecords: Schema.Natural;
271
+ readonly maxTargetRecords: Schema.Natural;
272
+ readonly maxEntries: Schema.Natural;
273
+ readonly maxOutputRecords: Schema.Natural;
97
274
  readonly maxOutputBytes: Schema.ByteSize;
98
- readonly maxInheritedRecords: Schema.Finite;
275
+ readonly maxInheritedRecords: Schema.Natural;
99
276
  }> & {
100
277
  constrained: {
101
278
  readonly maxEncodedBytes: ByteSize.ByteSize;
@@ -1 +1 @@
1
- {"version":3,"file":"SnapshotDelta.d.ts","sourceRoot":"","sources":["../src/SnapshotDelta.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAE3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAQxC,kDAAkD;AAClD,eAAO,MAAM,mBAAmB,eAA2C,CAAA;AAC3E,kDAAkD;AAClD,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAA;AAE5D,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;CACpD;AAID,gBAAgB;AAChB,eAAO,MAAM,iBAAiB,UAAW,MAAM,KAAG,aAIjD,CAAA;AAED,gBAAgB;AAChB,eAAO,MAAM,kBAAkB,UAAW,aAAa,KAAG,MAAM,GAAG,SAAsC,CAAA;AAEzG,6DAA6D;AAC7D,eAAO,MAAM,aAAa,8CAEzB,CAAA;AAED,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,4DAAoD,CAAA;AACjF,+DAA+D;AAC/D,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAA;AAE3D,oEAAoE;AACpE,eAAO,MAAM,kBAAkB,4IAY7B,CAAA;AACF,2DAA2D;AAC3D,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC,IAAI,CAAA;AAI/D;;;;;GAKG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;IASzB,CAAA;AACF,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AAEvD,oDAAoD;AACpD,eAAO,MAAM,sBAAsB;IACjC,6FAA6F;;EAE7F,CAAA;AACF,uDAAuD;AACvD,MAAM,MAAM,sBAAsB,GAAG,OAAO,sBAAsB,CAAC,IAAI,CAAA;;;;AAEvE,uGAAuG;AACvG,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAC9B,CAAC;CAAG;AAEL,QAAA,MAAM,yBAAyB;;;;;;;;;;;EAW7B,CAAA;AACF,iGAAiG;AACjG,MAAM,MAAM,mBAAmB,GAAG,OAAO,yBAAyB,CAAC,IAAI,CAAA;AAEvE,kFAAkF;AAClF,eAAO,MAAM,uBAAuB,WAAY,mBAAmB,KAAG,mBACxC,CAAA;AA2B9B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAG9B,CAAA"}
1
+ {"version":3,"file":"SnapshotDelta.d.ts","sourceRoot":"","sources":["../src/SnapshotDelta.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAA;AAE3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAGxC;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,gCAA+D,CAAA;AAEjG;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,mBAAmB,CAAA;AAE5D;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;CACpD;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,8CAA0D,CAAA;AAEpF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,4DAAoD,CAAA;AAEjF;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAA;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,4IAY7B,CAAA;AAEF;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC,IAAI,CAAA;AAI/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;IASzB,CAAA;AAEF;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC,IAAI,CAAA;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,sBAAsB;IACjC,6FAA6F;;EAE7F,CAAA;AAEF;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,OAAO,sBAAsB,CAAC,IAAI,CAAA;;;;AAEvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAC9B,CAAC;CAAG;AAEL,QAAA,MAAM,yBAAyB;;;;;;;;;;;EAW7B,CAAA;AAEF;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,yBAAyB,CAAC,IAAI,CAAA;AAEvE;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,WAAY,mBAAmB,KAAG,mBACxC,CAAA;AA4B9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAG9B,CAAA"}