@smthrs/artifacts 0.0.0-stage → 1.0.0-rc.12

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 (171) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/LICENSE +21 -0
  3. package/README.md +175 -2
  4. package/dist/cjs/ArtifactBackupLease.d.ts +34 -0
  5. package/dist/cjs/ArtifactBackupLease.d.ts.map +1 -0
  6. package/dist/cjs/ArtifactBackupLease.js +183 -0
  7. package/dist/cjs/ArtifactBackupLease.js.map +7 -0
  8. package/dist/cjs/ArtifactStore.d.ts +129 -0
  9. package/dist/cjs/ArtifactStore.d.ts.map +1 -0
  10. package/dist/cjs/ArtifactStore.js +73 -0
  11. package/dist/cjs/ArtifactStore.js.map +7 -0
  12. package/dist/cjs/ArtifactStoreError.d.ts +82 -0
  13. package/dist/cjs/ArtifactStoreError.d.ts.map +1 -0
  14. package/dist/cjs/ArtifactStoreError.js +72 -0
  15. package/dist/cjs/ArtifactStoreError.js.map +7 -0
  16. package/dist/cjs/ArtifactStoreMetrics.d.ts +70 -0
  17. package/dist/cjs/ArtifactStoreMetrics.d.ts.map +1 -0
  18. package/dist/cjs/ArtifactStoreMetrics.js +51 -0
  19. package/dist/cjs/ArtifactStoreMetrics.js.map +7 -0
  20. package/dist/cjs/ArtifactSweep.d.ts +185 -0
  21. package/dist/cjs/ArtifactSweep.d.ts.map +1 -0
  22. package/dist/cjs/ArtifactSweep.js +171 -0
  23. package/dist/cjs/ArtifactSweep.js.map +7 -0
  24. package/dist/cjs/CombinedArtifacts.d.ts +103 -0
  25. package/dist/cjs/CombinedArtifacts.d.ts.map +1 -0
  26. package/dist/cjs/CombinedArtifacts.js +189 -0
  27. package/dist/cjs/CombinedArtifacts.js.map +7 -0
  28. package/dist/cjs/FileLease.d.ts +117 -0
  29. package/dist/cjs/FileLease.d.ts.map +1 -0
  30. package/dist/cjs/FileLease.js +208 -0
  31. package/dist/cjs/FileLease.js.map +7 -0
  32. package/dist/cjs/FileSystemArtifactStore.d.ts +93 -0
  33. package/dist/cjs/FileSystemArtifactStore.d.ts.map +1 -0
  34. package/dist/cjs/FileSystemArtifactStore.js +276 -0
  35. package/dist/cjs/FileSystemArtifactStore.js.map +7 -0
  36. package/dist/cjs/MemoryArtifactStore.d.ts +25 -0
  37. package/dist/cjs/MemoryArtifactStore.d.ts.map +1 -0
  38. package/dist/cjs/MemoryArtifactStore.js +84 -0
  39. package/dist/cjs/MemoryArtifactStore.js.map +7 -0
  40. package/dist/cjs/NoopArtifactStore.d.ts +17 -0
  41. package/dist/cjs/NoopArtifactStore.d.ts.map +1 -0
  42. package/dist/cjs/NoopArtifactStore.js +46 -0
  43. package/dist/cjs/NoopArtifactStore.js.map +7 -0
  44. package/dist/cjs/RemoteArtifacts.d.ts +237 -0
  45. package/dist/cjs/RemoteArtifacts.d.ts.map +1 -0
  46. package/dist/cjs/RemoteArtifacts.js +405 -0
  47. package/dist/cjs/RemoteArtifacts.js.map +7 -0
  48. package/dist/cjs/index.d.ts +65 -0
  49. package/dist/cjs/index.d.ts.map +1 -0
  50. package/dist/cjs/index.js +47 -0
  51. package/dist/cjs/index.js.map +7 -0
  52. package/dist/cjs/internal/ArtifactLocks.d.ts +30 -0
  53. package/dist/cjs/internal/ArtifactLocks.d.ts.map +1 -0
  54. package/dist/cjs/internal/ArtifactLocks.js +93 -0
  55. package/dist/cjs/internal/ArtifactLocks.js.map +7 -0
  56. package/dist/cjs/internal/ArtifactPath.d.ts +19 -0
  57. package/dist/cjs/internal/ArtifactPath.d.ts.map +1 -0
  58. package/dist/cjs/internal/ArtifactPath.js +74 -0
  59. package/dist/cjs/internal/ArtifactPath.js.map +7 -0
  60. package/dist/cjs/measureBytes.d.ts +18 -0
  61. package/dist/cjs/measureBytes.d.ts.map +1 -0
  62. package/dist/cjs/measureBytes.js +43 -0
  63. package/dist/cjs/measureBytes.js.map +7 -0
  64. package/dist/cjs/package.json +1 -0
  65. package/dist/cjs/snapshotBytes.d.ts +19 -0
  66. package/dist/cjs/snapshotBytes.d.ts.map +1 -0
  67. package/dist/cjs/snapshotBytes.js +41 -0
  68. package/dist/cjs/snapshotBytes.js.map +7 -0
  69. package/dist/cjs/validateDigest.d.ts +22 -0
  70. package/dist/cjs/validateDigest.d.ts.map +1 -0
  71. package/dist/cjs/validateDigest.js +42 -0
  72. package/dist/cjs/validateDigest.js.map +7 -0
  73. package/dist/esm/ArtifactBackupLease.d.ts +34 -0
  74. package/dist/esm/ArtifactBackupLease.d.ts.map +1 -0
  75. package/dist/esm/ArtifactBackupLease.js +126 -0
  76. package/dist/esm/ArtifactBackupLease.js.map +1 -0
  77. package/dist/esm/ArtifactStore.d.ts +129 -0
  78. package/dist/esm/ArtifactStore.d.ts.map +1 -0
  79. package/dist/esm/ArtifactStore.js +83 -0
  80. package/dist/esm/ArtifactStore.js.map +1 -0
  81. package/dist/esm/ArtifactStoreError.d.ts +82 -0
  82. package/dist/esm/ArtifactStoreError.d.ts.map +1 -0
  83. package/dist/esm/ArtifactStoreError.js +77 -0
  84. package/dist/esm/ArtifactStoreError.js.map +1 -0
  85. package/dist/esm/ArtifactStoreMetrics.d.ts +70 -0
  86. package/dist/esm/ArtifactStoreMetrics.d.ts.map +1 -0
  87. package/dist/esm/ArtifactStoreMetrics.js +77 -0
  88. package/dist/esm/ArtifactStoreMetrics.js.map +1 -0
  89. package/dist/esm/ArtifactSweep.d.ts +185 -0
  90. package/dist/esm/ArtifactSweep.d.ts.map +1 -0
  91. package/dist/esm/ArtifactSweep.js +210 -0
  92. package/dist/esm/ArtifactSweep.js.map +1 -0
  93. package/dist/esm/CombinedArtifacts.d.ts +103 -0
  94. package/dist/esm/CombinedArtifacts.d.ts.map +1 -0
  95. package/dist/esm/CombinedArtifacts.js +214 -0
  96. package/dist/esm/CombinedArtifacts.js.map +1 -0
  97. package/dist/esm/FileLease.d.ts +117 -0
  98. package/dist/esm/FileLease.d.ts.map +1 -0
  99. package/dist/esm/FileLease.js +249 -0
  100. package/dist/esm/FileLease.js.map +1 -0
  101. package/dist/esm/FileSystemArtifactStore.d.ts +93 -0
  102. package/dist/esm/FileSystemArtifactStore.d.ts.map +1 -0
  103. package/dist/esm/FileSystemArtifactStore.js +336 -0
  104. package/dist/esm/FileSystemArtifactStore.js.map +1 -0
  105. package/dist/esm/MemoryArtifactStore.d.ts +25 -0
  106. package/dist/esm/MemoryArtifactStore.d.ts.map +1 -0
  107. package/dist/esm/MemoryArtifactStore.js +67 -0
  108. package/dist/esm/MemoryArtifactStore.js.map +1 -0
  109. package/dist/esm/NoopArtifactStore.d.ts +17 -0
  110. package/dist/esm/NoopArtifactStore.d.ts.map +1 -0
  111. package/dist/esm/NoopArtifactStore.js +27 -0
  112. package/dist/esm/NoopArtifactStore.js.map +1 -0
  113. package/dist/esm/RemoteArtifacts.d.ts +237 -0
  114. package/dist/esm/RemoteArtifacts.d.ts.map +1 -0
  115. package/dist/esm/RemoteArtifacts.js +557 -0
  116. package/dist/esm/RemoteArtifacts.js.map +1 -0
  117. package/dist/esm/index.d.ts +65 -0
  118. package/dist/esm/index.d.ts.map +1 -0
  119. package/dist/esm/index.js +65 -0
  120. package/dist/esm/index.js.map +1 -0
  121. package/dist/esm/internal/ArtifactLocks.d.ts +30 -0
  122. package/dist/esm/internal/ArtifactLocks.d.ts.map +1 -0
  123. package/dist/esm/internal/ArtifactLocks.js +86 -0
  124. package/dist/esm/internal/ArtifactLocks.js.map +1 -0
  125. package/dist/esm/internal/ArtifactPath.d.ts +19 -0
  126. package/dist/esm/internal/ArtifactPath.d.ts.map +1 -0
  127. package/dist/esm/internal/ArtifactPath.js +59 -0
  128. package/dist/esm/internal/ArtifactPath.js.map +1 -0
  129. package/dist/esm/measureBytes.d.ts +18 -0
  130. package/dist/esm/measureBytes.d.ts.map +1 -0
  131. package/dist/esm/measureBytes.js +22 -0
  132. package/dist/esm/measureBytes.js.map +1 -0
  133. package/dist/esm/snapshotBytes.d.ts +19 -0
  134. package/dist/esm/snapshotBytes.d.ts.map +1 -0
  135. package/dist/esm/snapshotBytes.js +30 -0
  136. package/dist/esm/snapshotBytes.js.map +1 -0
  137. package/dist/esm/validateDigest.d.ts +22 -0
  138. package/dist/esm/validateDigest.d.ts.map +1 -0
  139. package/dist/esm/validateDigest.js +26 -0
  140. package/dist/esm/validateDigest.js.map +1 -0
  141. package/docs/README.md +202 -0
  142. package/docs/api.md +484 -0
  143. package/docs/concepts/content-addressing.md +174 -0
  144. package/docs/concepts/coordination.md +141 -0
  145. package/docs/concepts/tiers.md +147 -0
  146. package/docs/guides/fence-a-backup.md +123 -0
  147. package/docs/guides/reclaim-disk-space.md +143 -0
  148. package/docs/guides/serve-the-artifact-protocol.md +140 -0
  149. package/docs/guides/share-artifacts-across-machines.md +180 -0
  150. package/docs/guides/test-against-an-artifact-store.md +158 -0
  151. package/docs/installation.md +102 -0
  152. package/docs/quickstart.md +183 -0
  153. package/docs/troubleshooting.md +232 -0
  154. package/package.json +179 -3
  155. package/src/ArtifactBackupLease.ts +223 -0
  156. package/src/ArtifactStore.ts +152 -0
  157. package/src/ArtifactStoreError.ts +96 -0
  158. package/src/ArtifactStoreMetrics.ts +83 -0
  159. package/src/ArtifactSweep.ts +346 -0
  160. package/src/CombinedArtifacts.ts +369 -0
  161. package/src/FileLease.ts +397 -0
  162. package/src/FileSystemArtifactStore.ts +459 -0
  163. package/src/MemoryArtifactStore.ts +83 -0
  164. package/src/NoopArtifactStore.ts +30 -0
  165. package/src/RemoteArtifacts.ts +814 -0
  166. package/src/index.ts +71 -0
  167. package/src/internal/ArtifactLocks.ts +110 -0
  168. package/src/internal/ArtifactPath.ts +72 -0
  169. package/src/measureBytes.ts +28 -0
  170. package/src/snapshotBytes.ts +34 -0
  171. package/src/validateDigest.ts +31 -0
@@ -0,0 +1,129 @@
1
+ /**
2
+ * The content-addressed artifact store: bytes addressed by their own SHA-256
3
+ * digest.
4
+ *
5
+ * It is deliberately *not* the step cache: the step cache maps a step key to a
6
+ * recorded result, while large result bytes live here under their digest. The
7
+ * two tiers remain separate because artifacts must be published before a cache
8
+ * record may reference them. See the package README and
9
+ * {@link https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/plan/docs/concepts/step-keys.md | step-key documentation}.
10
+ *
11
+ * This module defines the contract: the address schema, the service interface
12
+ * and tag, and one layer per local implementation. The errors, byte helpers,
13
+ * and implementations are defined in the modules named for them and re-exported
14
+ * here unchanged, so this subpath and the root `ArtifactStore` namespace keep
15
+ * their whole surface.
16
+ *
17
+ * @since 1.0.0-rc.0
18
+ */
19
+ import { Sha256 } from "@smthrs/crypto";
20
+ import * as Context from "effect/Context";
21
+ import type * as Crypto from "effect/Crypto";
22
+ import * as Effect from "effect/Effect";
23
+ import * as FileSystem from "effect/FileSystem";
24
+ import * as Layer from "effect/Layer";
25
+ import * as Path from "effect/Path";
26
+ import type { ArtifactCorruption, ArtifactMissing, ArtifactStoreError } from "./ArtifactStoreError.ts";
27
+ import { type FileSystemOptions } from "./FileSystemArtifactStore.ts";
28
+ export { ArtifactCorruption, ArtifactMissing, ArtifactStoreError, ArtifactStoreErrorCode } from "./ArtifactStoreError.ts";
29
+ export { defaultDirectory, type FileSystemOptions, makeFileSystem } from "./FileSystemArtifactStore.ts";
30
+ export { measureBytes } from "./measureBytes.ts";
31
+ export { makeMemory } from "./MemoryArtifactStore.ts";
32
+ export { makeNoop } from "./NoopArtifactStore.ts";
33
+ export { snapshotBytes } from "./snapshotBytes.ts";
34
+ export { validateDigest } from "./validateDigest.ts";
35
+ /**
36
+ * Schema for a content address: exactly 64 lowercase hexadecimal SHA-256
37
+ * characters, branded by `@smthrs/crypto`. Re-exported so a consumer never has
38
+ * to reach past this package for the address type it stores under.
39
+ *
40
+ * @category schemas
41
+ * @since 1.0.0-rc.0
42
+ * @slop
43
+ */
44
+ export declare const Digest: import("effect/Schema").brand<import("effect/Schema").String, "@smthrs/crypto/Sha256/Digest">;
45
+ /**
46
+ * A content address produced by this store.
47
+ *
48
+ * Read operations accept a plain `string` rather than this brand on purpose: a
49
+ * digest read back out of a durable row is untrusted input, so the store
50
+ * validates it (see {@link ArtifactStoreError}'s `invalid_digest` code) instead
51
+ * of asking every caller to re-brand a persisted column. `put` returns the
52
+ * brand, because it measured the bytes itself.
53
+ *
54
+ * @category models
55
+ * @since 1.0.0-rc.0
56
+ * @slop
57
+ */
58
+ export type Digest = typeof Sha256.Digest.Type;
59
+ /**
60
+ * Content-addressed blob storage.
61
+ *
62
+ * The contract's ergonomics follow Effect's own `KeyValueStore`
63
+ * (`effect/persistence/KeyValueStore`): a small set of total
64
+ * operations over one address space, with a single typed error family, so a
65
+ * memory, filesystem, or network implementation is the same shape.
66
+ * `findMissing` is Bazel's `MissingDigestsFinder` — one batched round trip
67
+ * whose result is guaranteed to be a subset of its input — because a
68
+ * per-digest existence probe over a network tier is the wrong shape entirely.
69
+ *
70
+ * @category models
71
+ * @since 1.0.0-rc.0
72
+ * @slop
73
+ */
74
+ export interface Service {
75
+ /**
76
+ * Stores `bytes` under their own SHA-256 digest and returns that address.
77
+ * Storing the same bytes twice is idempotent.
78
+ */
79
+ readonly put: (bytes: Uint8Array) => Effect.Effect<Digest, ArtifactStoreError, Crypto.Crypto>;
80
+ /**
81
+ * Reads the bytes stored at `digest`, verifying that they still hash to it.
82
+ */
83
+ readonly get: (digest: string) => Effect.Effect<Uint8Array, ArtifactMissing | ArtifactCorruption | ArtifactStoreError, Crypto.Crypto>;
84
+ /** Whether this tier holds an artifact at `digest`. */
85
+ readonly has: (digest: string) => Effect.Effect<boolean, ArtifactStoreError>;
86
+ /**
87
+ * Which of `digests` this tier does not hold. The returned array is
88
+ * guaranteed to be a subset of the input and free of duplicates.
89
+ */
90
+ readonly findMissing: (digests: Iterable<string>) => Effect.Effect<Array<string>, ArtifactStoreError>;
91
+ }
92
+ declare const ArtifactStore_base: Context.ServiceClass<ArtifactStore, "@smthrs/artifacts/ArtifactStore", Service>;
93
+ /**
94
+ * Service tag for the content-addressed artifact store.
95
+ *
96
+ * The identity string equals this module's package path, per the house rule
97
+ * that an identity is the defining module path.
98
+ *
99
+ * @category services
100
+ * @since 1.0.0-rc.0
101
+ * @slop
102
+ */
103
+ export declare class ArtifactStore extends ArtifactStore_base {
104
+ }
105
+ /**
106
+ * Provides the filesystem-backed artifact store.
107
+ *
108
+ * @category layers
109
+ * @since 1.0.0-rc.0
110
+ * @slop
111
+ */
112
+ export declare const layerFileSystem: (options?: FileSystemOptions) => Layer.Layer<ArtifactStore, never, FileSystem.FileSystem | Path.Path>;
113
+ /**
114
+ * Provides an in-memory artifact store.
115
+ *
116
+ * @category layers
117
+ * @since 1.0.0-rc.0
118
+ * @slop
119
+ */
120
+ export declare const layerMemory: Layer.Layer<ArtifactStore>;
121
+ /**
122
+ * Provides a no-op artifact store.
123
+ *
124
+ * @category layers
125
+ * @since 1.0.0-rc.0
126
+ * @slop
127
+ */
128
+ export declare const layerNoop: (overrides?: Partial<Service>) => Layer.Layer<ArtifactStore>;
129
+ //# sourceMappingURL=ArtifactStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArtifactStore.d.ts","sourceRoot":"","sources":["../../src/ArtifactStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAA;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACtG,OAAO,EAAE,KAAK,iBAAiB,EAAkB,MAAM,8BAA8B,CAAA;AAIrF,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AACvG,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,+FAAgB,CAAA;AAEnC;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAA;AAE9C;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,OAAO;IACtB;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;IAC7F;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,CACZ,MAAM,EAAE,MAAM,KACX,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,GAAG,kBAAkB,GAAG,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;IACxG,uDAAuD;IACvD,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAA;IAC5E;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,CACpB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,KACtB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAA;CACtD;;AAED;;;;;;;;;GASG;AACH,qBAAa,aAAc,SAAQ,kBAA4E;CAAG;AAElH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAS,iBAAsB,KAC9B,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAGjE,CAAA;AAEL;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,aAAa,CAAwD,CAAA;AAE3G;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAI,YAAW,OAAO,CAAC,OAAO,CAAM,KAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CACnC,CAAA"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var ArtifactStore_exports = {};
30
+ __export(ArtifactStore_exports, {
31
+ ArtifactCorruption: () => import_ArtifactStoreError.ArtifactCorruption,
32
+ ArtifactMissing: () => import_ArtifactStoreError.ArtifactMissing,
33
+ ArtifactStore: () => ArtifactStore,
34
+ ArtifactStoreError: () => import_ArtifactStoreError.ArtifactStoreError,
35
+ ArtifactStoreErrorCode: () => import_ArtifactStoreError.ArtifactStoreErrorCode,
36
+ Digest: () => Digest,
37
+ defaultDirectory: () => import_FileSystemArtifactStore2.defaultDirectory,
38
+ layerFileSystem: () => layerFileSystem,
39
+ layerMemory: () => layerMemory,
40
+ layerNoop: () => layerNoop,
41
+ makeFileSystem: () => import_FileSystemArtifactStore2.makeFileSystem,
42
+ makeMemory: () => import_MemoryArtifactStore2.makeMemory,
43
+ makeNoop: () => import_NoopArtifactStore2.makeNoop,
44
+ measureBytes: () => import_measureBytes.measureBytes,
45
+ snapshotBytes: () => import_snapshotBytes.snapshotBytes,
46
+ validateDigest: () => import_validateDigest.validateDigest
47
+ });
48
+ module.exports = __toCommonJS(ArtifactStore_exports);
49
+ var import_crypto = require("@smthrs/crypto");
50
+ var Context = __toESM(require("effect/Context"), 1);
51
+ var Effect = __toESM(require("effect/Effect"), 1);
52
+ var FileSystem = __toESM(require("effect/FileSystem"), 1);
53
+ var Layer = __toESM(require("effect/Layer"), 1);
54
+ var Path = __toESM(require("effect/Path"), 1);
55
+ var import_FileSystemArtifactStore = require("./FileSystemArtifactStore.js");
56
+ var import_MemoryArtifactStore = require("./MemoryArtifactStore.js");
57
+ var import_NoopArtifactStore = require("./NoopArtifactStore.js");
58
+ var import_ArtifactStoreError = require("./ArtifactStoreError.js");
59
+ var import_FileSystemArtifactStore2 = require("./FileSystemArtifactStore.js");
60
+ var import_measureBytes = require("./measureBytes.js");
61
+ var import_MemoryArtifactStore2 = require("./MemoryArtifactStore.js");
62
+ var import_NoopArtifactStore2 = require("./NoopArtifactStore.js");
63
+ var import_snapshotBytes = require("./snapshotBytes.js");
64
+ var import_validateDigest = require("./validateDigest.js");
65
+ const Digest = import_crypto.Sha256.Digest;
66
+ class ArtifactStore extends Context.Service()("@smthrs/artifacts/ArtifactStore") {
67
+ }
68
+ const layerFileSystem = (options = {}) => Layer.effect(ArtifactStore)(Effect.gen(function* () {
69
+ return (0, import_FileSystemArtifactStore.makeFileSystem)(yield* FileSystem.FileSystem, yield* Path.Path, options);
70
+ }));
71
+ const layerMemory = Layer.effect(ArtifactStore)(Effect.sync(import_MemoryArtifactStore.makeMemory));
72
+ const layerNoop = (overrides = {}) => Layer.succeed(ArtifactStore)((0, import_NoopArtifactStore.makeNoop)(overrides));
73
+ //# sourceMappingURL=ArtifactStore.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ArtifactStore.ts"],
4
+ "sourcesContent": ["/**\n * The content-addressed artifact store: bytes addressed by their own SHA-256\n * digest.\n *\n * It is deliberately *not* the step cache: the step cache maps a step key to a\n * recorded result, while large result bytes live here under their digest. The\n * two tiers remain separate because artifacts must be published before a cache\n * record may reference them. See the package README and\n * {@link https://github.com/smithersai/smithers/blob/main/packages/smithers/flows/plan/docs/concepts/step-keys.md | step-key documentation}.\n *\n * This module defines the contract: the address schema, the service interface\n * and tag, and one layer per local implementation. The errors, byte helpers,\n * and implementations are defined in the modules named for them and re-exported\n * here unchanged, so this subpath and the root `ArtifactStore` namespace keep\n * their whole surface.\n *\n * @since 1.0.0-rc.0\n */\n\nimport { Sha256 } from \"@smthrs/crypto\"\nimport * as Context from \"effect/Context\"\nimport type * as Crypto from \"effect/Crypto\"\nimport * as Effect from \"effect/Effect\"\nimport * as FileSystem from \"effect/FileSystem\"\nimport * as Layer from \"effect/Layer\"\nimport * as Path from \"effect/Path\"\nimport type { ArtifactCorruption, ArtifactMissing, ArtifactStoreError } from \"./ArtifactStoreError.ts\"\nimport { type FileSystemOptions, makeFileSystem } from \"./FileSystemArtifactStore.ts\"\nimport { makeMemory } from \"./MemoryArtifactStore.ts\"\nimport { makeNoop } from \"./NoopArtifactStore.ts\"\n\nexport {\n ArtifactCorruption,\n ArtifactMissing,\n ArtifactStoreError,\n ArtifactStoreErrorCode\n} from \"./ArtifactStoreError.ts\"\nexport { defaultDirectory, type FileSystemOptions, makeFileSystem } from \"./FileSystemArtifactStore.ts\"\nexport { measureBytes } from \"./measureBytes.ts\"\nexport { makeMemory } from \"./MemoryArtifactStore.ts\"\nexport { makeNoop } from \"./NoopArtifactStore.ts\"\nexport { snapshotBytes } from \"./snapshotBytes.ts\"\nexport { validateDigest } from \"./validateDigest.ts\"\n\n/**\n * Schema for a content address: exactly 64 lowercase hexadecimal SHA-256\n * characters, branded by `@smthrs/crypto`. Re-exported so a consumer never has\n * to reach past this package for the address type it stores under.\n *\n * @category schemas\n * @since 1.0.0-rc.0\n * @slop\n */\nexport const Digest = Sha256.Digest\n\n/**\n * A content address produced by this store.\n *\n * Read operations accept a plain `string` rather than this brand on purpose: a\n * digest read back out of a durable row is untrusted input, so the store\n * validates it (see {@link ArtifactStoreError}'s `invalid_digest` code) instead\n * of asking every caller to re-brand a persisted column. `put` returns the\n * brand, because it measured the bytes itself.\n *\n * @category models\n * @since 1.0.0-rc.0\n * @slop\n */\nexport type Digest = typeof Sha256.Digest.Type\n\n/**\n * Content-addressed blob storage.\n *\n * The contract's ergonomics follow Effect's own `KeyValueStore`\n * (`effect/persistence/KeyValueStore`): a small set of total\n * operations over one address space, with a single typed error family, so a\n * memory, filesystem, or network implementation is the same shape.\n * `findMissing` is Bazel's `MissingDigestsFinder` \u2014 one batched round trip\n * whose result is guaranteed to be a subset of its input \u2014 because a\n * per-digest existence probe over a network tier is the wrong shape entirely.\n *\n * @category models\n * @since 1.0.0-rc.0\n * @slop\n */\nexport interface Service {\n /**\n * Stores `bytes` under their own SHA-256 digest and returns that address.\n * Storing the same bytes twice is idempotent.\n */\n readonly put: (bytes: Uint8Array) => Effect.Effect<Digest, ArtifactStoreError, Crypto.Crypto>\n /**\n * Reads the bytes stored at `digest`, verifying that they still hash to it.\n */\n readonly get: (\n digest: string\n ) => Effect.Effect<Uint8Array, ArtifactMissing | ArtifactCorruption | ArtifactStoreError, Crypto.Crypto>\n /** Whether this tier holds an artifact at `digest`. */\n readonly has: (digest: string) => Effect.Effect<boolean, ArtifactStoreError>\n /**\n * Which of `digests` this tier does not hold. The returned array is\n * guaranteed to be a subset of the input and free of duplicates.\n */\n readonly findMissing: (\n digests: Iterable<string>\n ) => Effect.Effect<Array<string>, ArtifactStoreError>\n}\n\n/**\n * Service tag for the content-addressed artifact store.\n *\n * The identity string equals this module's package path, per the house rule\n * that an identity is the defining module path.\n *\n * @category services\n * @since 1.0.0-rc.0\n * @slop\n */\nexport class ArtifactStore extends Context.Service<ArtifactStore, Service>()(\"@smthrs/artifacts/ArtifactStore\") {}\n\n/**\n * Provides the filesystem-backed artifact store.\n *\n * @category layers\n * @since 1.0.0-rc.0\n * @slop\n */\nexport const layerFileSystem = (\n options: FileSystemOptions = {}\n): Layer.Layer<ArtifactStore, never, FileSystem.FileSystem | Path.Path> =>\n Layer.effect(ArtifactStore)(Effect.gen(function*() {\n return makeFileSystem(yield* FileSystem.FileSystem, yield* Path.Path, options)\n }))\n\n/**\n * Provides an in-memory artifact store.\n *\n * @category layers\n * @since 1.0.0-rc.0\n * @slop\n */\nexport const layerMemory: Layer.Layer<ArtifactStore> = Layer.effect(ArtifactStore)(Effect.sync(makeMemory))\n\n/**\n * Provides a no-op artifact store.\n *\n * @category layers\n * @since 1.0.0-rc.0\n * @slop\n */\nexport const layerNoop = (overrides: Partial<Service> = {}): Layer.Layer<ArtifactStore> =>\n Layer.succeed(ArtifactStore)(makeNoop(overrides))\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,oBAAuB;AACvB,cAAyB;AAEzB,aAAwB;AACxB,iBAA4B;AAC5B,YAAuB;AACvB,WAAsB;AAEtB,qCAAuD;AACvD,iCAA2B;AAC3B,+BAAyB;AAEzB,gCAKO;AACP,IAAAA,kCAAyE;AACzE,0BAA6B;AAC7B,IAAAC,8BAA2B;AAC3B,IAAAC,4BAAyB;AACzB,2BAA8B;AAC9B,4BAA+B;AAWxB,MAAM,SAAS,qBAAO;AAiEtB,MAAM,sBAAsB,QAAQ,QAAgC,EAAE,iCAAiC,EAAE;AAAC;AAS1G,MAAM,kBAAkB,CAC7B,UAA6B,CAAC,MAE9B,MAAM,OAAO,aAAa,EAAE,OAAO,IAAI,aAAY;AACjD,aAAO,+CAAe,OAAO,WAAW,YAAY,OAAO,KAAK,MAAM,OAAO;AAC/E,CAAC,CAAC;AASG,MAAM,cAA0C,MAAM,OAAO,aAAa,EAAE,OAAO,KAAK,qCAAU,CAAC;AASnG,MAAM,YAAY,CAAC,YAA8B,CAAC,MACvD,MAAM,QAAQ,aAAa,MAAE,mCAAS,SAAS,CAAC;",
6
+ "names": ["import_FileSystemArtifactStore", "import_MemoryArtifactStore", "import_NoopArtifactStore"]
7
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * The artifact store's typed failures: a refusal of the store itself, the
3
+ * typed miss, and a digest mismatch, with the stable codes a refusal carries.
4
+ *
5
+ * @since 1.0.0-rc.0
6
+ */
7
+ import * as Schema from "effect/Schema";
8
+ /**
9
+ * Stable error codes returned by artifact store operations.
10
+ *
11
+ * @category models
12
+ * @since 1.0.0-rc.0
13
+ * @slop
14
+ */
15
+ export declare const ArtifactStoreErrorCode: Schema.Literals<readonly ["digest_failed", "invalid_configuration", "invalid_digest", "unavailable", "transport_failed"]>;
16
+ /**
17
+ * Stable error codes returned by artifact store operations.
18
+ *
19
+ * @category models
20
+ * @since 1.0.0-rc.0
21
+ * @slop
22
+ */
23
+ export type ArtifactStoreErrorCode = typeof ArtifactStoreErrorCode.Type;
24
+ declare const ArtifactStoreError_base: Schema.Class<ArtifactStoreError, Schema.TaggedStruct<"@smthrs/artifacts/ArtifactStoreError", {
25
+ readonly code: Schema.Literals<readonly ["digest_failed", "invalid_configuration", "invalid_digest", "unavailable", "transport_failed"]>;
26
+ readonly message: Schema.String;
27
+ readonly cause: Schema.optional<Schema.Unknown>;
28
+ }>, import("effect/Cause").YieldableError>;
29
+ /**
30
+ * A typed failure of the store itself: the host or crypto provider refused an
31
+ * operation, the remote tier refused a request, or the caller supplied invalid
32
+ * configuration or an invalid content address.
33
+ *
34
+ * Distinct from {@link ArtifactMissing} and {@link ArtifactCorruption} on
35
+ * purpose. A miss is an ordinary, expected outcome that a second tier may
36
+ * still satisfy; corruption is an integrity violation of the store's strongest
37
+ * invariant. `invalid_configuration` and `invalid_digest` are permanent;
38
+ * retryability of host, crypto, and transport failures depends on the cause.
39
+ *
40
+ * @category errors
41
+ * @since 1.0.0-rc.0
42
+ * @slop
43
+ */
44
+ export declare class ArtifactStoreError extends ArtifactStoreError_base {
45
+ }
46
+ declare const ArtifactMissing_base: Schema.Class<ArtifactMissing, Schema.TaggedStruct<"@smthrs/artifacts/ArtifactMissing", {
47
+ readonly code: Schema.Literal<"artifact_missing">;
48
+ readonly digest: Schema.brand<Schema.String, "@smthrs/crypto/Sha256/Digest">;
49
+ }>, import("effect/Cause").YieldableError>;
50
+ /**
51
+ * The typed miss: this tier holds no bytes at the requested address.
52
+ *
53
+ * A miss is not a failure of the store — it is the answer a read-through
54
+ * composition is built to act on, so it is a distinct tag rather than an
55
+ * `unavailable` code that a caller would have to string-match.
56
+ *
57
+ * @category errors
58
+ * @since 1.0.0-rc.0
59
+ * @slop
60
+ */
61
+ export declare class ArtifactMissing extends ArtifactMissing_base {
62
+ }
63
+ declare const ArtifactCorruption_base: Schema.Class<ArtifactCorruption, Schema.TaggedStruct<"@smthrs/artifacts/ArtifactCorruption", {
64
+ readonly code: Schema.Literal<"artifact_corruption">;
65
+ readonly recordedDigest: Schema.brand<Schema.String, "@smthrs/crypto/Sha256/Digest">;
66
+ readonly measuredDigest: Schema.brand<Schema.String, "@smthrs/crypto/Sha256/Digest">;
67
+ }>, import("effect/Cause").YieldableError>;
68
+ /**
69
+ * Bytes stored at a content address no longer hash to it.
70
+ *
71
+ * Every read is digest-verified, so a truncated blob left by a crashing writer
72
+ * or by disk corruption is refused rather than handed back as if it were the
73
+ * recorded artifact.
74
+ *
75
+ * @category errors
76
+ * @since 1.0.0-rc.0
77
+ * @slop
78
+ */
79
+ export declare class ArtifactCorruption extends ArtifactCorruption_base {
80
+ }
81
+ export {};
82
+ //# sourceMappingURL=ArtifactStoreError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArtifactStoreError.d.ts","sourceRoot":"","sources":["../../src/ArtifactStoreError.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,2HAMjC,CAAA;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,sBAAsB,GAAG,OAAO,sBAAsB,CAAC,IAAI,CAAA;;;;;;AAEvE;;;;;;;;;;;;;;GAcG;AACH,qBAAa,kBAAmB,SAAQ,uBAOvC;CAAG;;;;;AAEJ;;;;;;;;;;GAUG;AACH,qBAAa,eAAgB,SAAQ,oBAMpC;CAAG;;;;;;AAEJ;;;;;;;;;;GAUG;AACH,qBAAa,kBAAmB,SAAQ,uBAOvC;CAAG"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var ArtifactStoreError_exports = {};
30
+ __export(ArtifactStoreError_exports, {
31
+ ArtifactCorruption: () => ArtifactCorruption,
32
+ ArtifactMissing: () => ArtifactMissing,
33
+ ArtifactStoreError: () => ArtifactStoreError,
34
+ ArtifactStoreErrorCode: () => ArtifactStoreErrorCode
35
+ });
36
+ module.exports = __toCommonJS(ArtifactStoreError_exports);
37
+ var import_crypto = require("@smthrs/crypto");
38
+ var Schema = __toESM(require("effect/Schema"), 1);
39
+ const ArtifactStoreErrorCode = Schema.Literals([
40
+ "digest_failed",
41
+ "invalid_configuration",
42
+ "invalid_digest",
43
+ "unavailable",
44
+ "transport_failed"
45
+ ]);
46
+ class ArtifactStoreError extends Schema.TaggedError()(
47
+ "@smthrs/artifacts/ArtifactStoreError",
48
+ {
49
+ code: ArtifactStoreErrorCode,
50
+ message: Schema.String,
51
+ cause: Schema.optional(Schema.Unknown)
52
+ }
53
+ ) {
54
+ }
55
+ class ArtifactMissing extends Schema.TaggedError()(
56
+ "@smthrs/artifacts/ArtifactMissing",
57
+ {
58
+ code: Schema.Literal("artifact_missing"),
59
+ digest: import_crypto.Sha256.Digest
60
+ }
61
+ ) {
62
+ }
63
+ class ArtifactCorruption extends Schema.TaggedError()(
64
+ "@smthrs/artifacts/ArtifactCorruption",
65
+ {
66
+ code: Schema.Literal("artifact_corruption"),
67
+ recordedDigest: import_crypto.Sha256.Digest,
68
+ measuredDigest: import_crypto.Sha256.Digest
69
+ }
70
+ ) {
71
+ }
72
+ //# sourceMappingURL=ArtifactStoreError.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ArtifactStoreError.ts"],
4
+ "sourcesContent": ["/**\n * The artifact store's typed failures: a refusal of the store itself, the\n * typed miss, and a digest mismatch, with the stable codes a refusal carries.\n *\n * @since 1.0.0-rc.0\n */\n\nimport { Sha256 } from \"@smthrs/crypto\"\nimport * as Schema from \"effect/Schema\"\n\n/**\n * Stable error codes returned by artifact store operations.\n *\n * @category models\n * @since 1.0.0-rc.0\n * @slop\n */\nexport const ArtifactStoreErrorCode = Schema.Literals([\n \"digest_failed\",\n \"invalid_configuration\",\n \"invalid_digest\",\n \"unavailable\",\n \"transport_failed\"\n])\n\n/**\n * Stable error codes returned by artifact store operations.\n *\n * @category models\n * @since 1.0.0-rc.0\n * @slop\n */\nexport type ArtifactStoreErrorCode = typeof ArtifactStoreErrorCode.Type\n\n/**\n * A typed failure of the store itself: the host or crypto provider refused an\n * operation, the remote tier refused a request, or the caller supplied invalid\n * configuration or an invalid content address.\n *\n * Distinct from {@link ArtifactMissing} and {@link ArtifactCorruption} on\n * purpose. A miss is an ordinary, expected outcome that a second tier may\n * still satisfy; corruption is an integrity violation of the store's strongest\n * invariant. `invalid_configuration` and `invalid_digest` are permanent;\n * retryability of host, crypto, and transport failures depends on the cause.\n *\n * @category errors\n * @since 1.0.0-rc.0\n * @slop\n */\nexport class ArtifactStoreError extends Schema.TaggedError<ArtifactStoreError>()(\n \"@smthrs/artifacts/ArtifactStoreError\",\n {\n code: ArtifactStoreErrorCode,\n message: Schema.String,\n cause: Schema.optional(Schema.Unknown)\n }\n) {}\n\n/**\n * The typed miss: this tier holds no bytes at the requested address.\n *\n * A miss is not a failure of the store \u2014 it is the answer a read-through\n * composition is built to act on, so it is a distinct tag rather than an\n * `unavailable` code that a caller would have to string-match.\n *\n * @category errors\n * @since 1.0.0-rc.0\n * @slop\n */\nexport class ArtifactMissing extends Schema.TaggedError<ArtifactMissing>()(\n \"@smthrs/artifacts/ArtifactMissing\",\n {\n code: Schema.Literal(\"artifact_missing\"),\n digest: Sha256.Digest\n }\n) {}\n\n/**\n * Bytes stored at a content address no longer hash to it.\n *\n * Every read is digest-verified, so a truncated blob left by a crashing writer\n * or by disk corruption is refused rather than handed back as if it were the\n * recorded artifact.\n *\n * @category errors\n * @since 1.0.0-rc.0\n * @slop\n */\nexport class ArtifactCorruption extends Schema.TaggedError<ArtifactCorruption>()(\n \"@smthrs/artifacts/ArtifactCorruption\",\n {\n code: Schema.Literal(\"artifact_corruption\"),\n recordedDigest: Sha256.Digest,\n measuredDigest: Sha256.Digest\n }\n) {}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,oBAAuB;AACvB,aAAwB;AASjB,MAAM,yBAAyB,OAAO,SAAS;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AA0BM,MAAM,2BAA2B,OAAO,YAAgC;AAAA,EAC7E;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,SAAS,OAAO;AAAA,IAChB,OAAO,OAAO,SAAS,OAAO,OAAO;AAAA,EACvC;AACF,EAAE;AAAC;AAaI,MAAM,wBAAwB,OAAO,YAA6B;AAAA,EACvE;AAAA,EACA;AAAA,IACE,MAAM,OAAO,QAAQ,kBAAkB;AAAA,IACvC,QAAQ,qBAAO;AAAA,EACjB;AACF,EAAE;AAAC;AAaI,MAAM,2BAA2B,OAAO,YAAgC;AAAA,EAC7E;AAAA,EACA;AAAA,IACE,MAAM,OAAO,QAAQ,qBAAqB;AAAA,IAC1C,gBAAgB,qBAAO;AAAA,IACvB,gBAAgB,qBAAO;AAAA,EACzB;AACF,EAAE;AAAC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Standard metric definitions for content-addressed artifact storage.
3
+ *
4
+ * This module only defines the metric handles, following the shape of Effect's
5
+ * `ClusterMetrics`. No exporter ships in this package; provide one — for
6
+ * example `@smthrs/observability` — and these counters appear in it.
7
+ *
8
+ * Only the local `ArtifactStore` implementations, filesystem and memory, update
9
+ * them. `RemoteArtifacts` is deliberately uninstrumented, and the counters carry
10
+ * no tier attribute, so read them as *local artifact store traffic* rather than
11
+ * as artifact operations:
12
+ *
13
+ * - a `CombinedArtifacts` read the local tier serves counts one get;
14
+ * - a read the shared tier serves counts NO get, because no local store
15
+ * answered it;
16
+ * - the write-back that materializes such a read counts a put, indistinguishable
17
+ * from a producer publishing new bytes.
18
+ *
19
+ * Attributing operations per tier needs the tier in the metric, which would
20
+ * change the published counter shape; until then this is what the numbers mean.
21
+ *
22
+ * The one shared-tier signal is {@link remoteFailure}: a `CombinedArtifacts`
23
+ * upload or write-back that was refused, or abandoned at its deadline.
24
+ *
25
+ * @since 1.0.0-rc.0
26
+ */
27
+ import * as Metric from "effect/Metric";
28
+ /**
29
+ * Counter over successful artifact puts. A put that deduplicated against an
30
+ * existing verified blob still counts: the caller stored bytes and received
31
+ * an address either way.
32
+ *
33
+ * @category metrics
34
+ * @since 1.0.0-rc.0
35
+ * @slop
36
+ */
37
+ export declare const puts: Metric.Counter<number>;
38
+ /**
39
+ * Counter over successful artifact gets. Missing and corrupt reads fail with
40
+ * their typed errors and are deliberately not counted here; they are error
41
+ * evidence, not throughput.
42
+ *
43
+ * @category metrics
44
+ * @since 1.0.0-rc.0
45
+ * @slop
46
+ */
47
+ export declare const gets: Metric.Counter<number>;
48
+ /**
49
+ * Counter over opportunistic `CombinedArtifacts` transfers that failed or hit
50
+ * their deadline and were dropped: `put`'s upload to the shared tier and
51
+ * `get`'s write-back into the local tier.
52
+ *
53
+ * Read the attributed views on {@link remoteFailure}: every update carries an
54
+ * `operation` attribute, so this bare handle aggregates nothing and always
55
+ * reads zero.
56
+ *
57
+ * @category metrics
58
+ * @since 1.0.0-rc.1
59
+ */
60
+ export declare const remoteFailures: Metric.Counter<number>;
61
+ /**
62
+ * `remoteFailures` views keyed by the dropped transfer.
63
+ *
64
+ * @category metrics
65
+ * @since 1.0.0-rc.1
66
+ */
67
+ export declare const remoteFailure: {
68
+ readonly [Operation in "put" | "write_back"]: Metric.Metric<number, Metric.CounterState<number>>;
69
+ };
70
+ //# sourceMappingURL=ArtifactStoreMetrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArtifactStoreMetrics.d.ts","sourceRoot":"","sources":["../../src/ArtifactStoreMetrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,wBAEf,CAAA;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,wBAEf,CAAA;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,wBAEzB,CAAA;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE;IAC1B,QAAQ,EAAE,SAAS,IAAI,KAAK,GAAG,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;CAIjG,CAAA"}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var ArtifactStoreMetrics_exports = {};
30
+ __export(ArtifactStoreMetrics_exports, {
31
+ gets: () => gets,
32
+ puts: () => puts,
33
+ remoteFailure: () => remoteFailure,
34
+ remoteFailures: () => remoteFailures
35
+ });
36
+ module.exports = __toCommonJS(ArtifactStoreMetrics_exports);
37
+ var Metric = __toESM(require("effect/Metric"), 1);
38
+ const puts = Metric.counter("flows_artifact_puts", {
39
+ description: "Successful artifact puts, including deduplicated ones"
40
+ });
41
+ const gets = Metric.counter("flows_artifact_gets", {
42
+ description: "Successful artifact gets"
43
+ });
44
+ const remoteFailures = Metric.counter("flows_artifact_remote_failures", {
45
+ description: "Dropped combined-artifact transfers by operation"
46
+ });
47
+ const remoteFailure = {
48
+ put: Metric.withAttributes(remoteFailures, { operation: "put" }),
49
+ write_back: Metric.withAttributes(remoteFailures, { operation: "write_back" })
50
+ };
51
+ //# sourceMappingURL=ArtifactStoreMetrics.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/ArtifactStoreMetrics.ts"],
4
+ "sourcesContent": ["/**\n * Standard metric definitions for content-addressed artifact storage.\n *\n * This module only defines the metric handles, following the shape of Effect's\n * `ClusterMetrics`. No exporter ships in this package; provide one \u2014 for\n * example `@smthrs/observability` \u2014 and these counters appear in it.\n *\n * Only the local `ArtifactStore` implementations, filesystem and memory, update\n * them. `RemoteArtifacts` is deliberately uninstrumented, and the counters carry\n * no tier attribute, so read them as *local artifact store traffic* rather than\n * as artifact operations:\n *\n * - a `CombinedArtifacts` read the local tier serves counts one get;\n * - a read the shared tier serves counts NO get, because no local store\n * answered it;\n * - the write-back that materializes such a read counts a put, indistinguishable\n * from a producer publishing new bytes.\n *\n * Attributing operations per tier needs the tier in the metric, which would\n * change the published counter shape; until then this is what the numbers mean.\n *\n * The one shared-tier signal is {@link remoteFailure}: a `CombinedArtifacts`\n * upload or write-back that was refused, or abandoned at its deadline.\n *\n * @since 1.0.0-rc.0\n */\n\nimport * as Metric from \"effect/Metric\"\n\n/**\n * Counter over successful artifact puts. A put that deduplicated against an\n * existing verified blob still counts: the caller stored bytes and received\n * an address either way.\n *\n * @category metrics\n * @since 1.0.0-rc.0\n * @slop\n */\nexport const puts = Metric.counter(\"flows_artifact_puts\", {\n description: \"Successful artifact puts, including deduplicated ones\"\n})\n\n/**\n * Counter over successful artifact gets. Missing and corrupt reads fail with\n * their typed errors and are deliberately not counted here; they are error\n * evidence, not throughput.\n *\n * @category metrics\n * @since 1.0.0-rc.0\n * @slop\n */\nexport const gets = Metric.counter(\"flows_artifact_gets\", {\n description: \"Successful artifact gets\"\n})\n\n/**\n * Counter over opportunistic `CombinedArtifacts` transfers that failed or hit\n * their deadline and were dropped: `put`'s upload to the shared tier and\n * `get`'s write-back into the local tier.\n *\n * Read the attributed views on {@link remoteFailure}: every update carries an\n * `operation` attribute, so this bare handle aggregates nothing and always\n * reads zero.\n *\n * @category metrics\n * @since 1.0.0-rc.1\n */\nexport const remoteFailures = Metric.counter(\"flows_artifact_remote_failures\", {\n description: \"Dropped combined-artifact transfers by operation\"\n})\n\n/**\n * `remoteFailures` views keyed by the dropped transfer.\n *\n * @category metrics\n * @since 1.0.0-rc.1\n */\nexport const remoteFailure: {\n readonly [Operation in \"put\" | \"write_back\"]: Metric.Metric<number, Metric.CounterState<number>>\n} = {\n put: Metric.withAttributes(remoteFailures, { operation: \"put\" }),\n write_back: Metric.withAttributes(remoteFailures, { operation: \"write_back\" })\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BA,aAAwB;AAWjB,MAAM,OAAO,OAAO,QAAQ,uBAAuB;AAAA,EACxD,aAAa;AACf,CAAC;AAWM,MAAM,OAAO,OAAO,QAAQ,uBAAuB;AAAA,EACxD,aAAa;AACf,CAAC;AAcM,MAAM,iBAAiB,OAAO,QAAQ,kCAAkC;AAAA,EAC7E,aAAa;AACf,CAAC;AAQM,MAAM,gBAET;AAAA,EACF,KAAK,OAAO,eAAe,gBAAgB,EAAE,WAAW,MAAM,CAAC;AAAA,EAC/D,YAAY,OAAO,eAAe,gBAAgB,EAAE,WAAW,aAAa,CAAC;AAC/E;",
6
+ "names": []
7
+ }