@effected/images 0.6.2 → 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/ImageCacheKey.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { DIGEST_PATTERN } from "./internal/digest.js";
2
2
  import { ImageCacheKeyError } from "./ImageCacheKeyError.js";
3
3
  import { canonicalJson } from "./internal/canonical.js";
4
- import { Crypto, Effect, Result, Schema } from "effect";
5
- import * as Hex from "effect/encoding/Hex";
4
+ import { Effect, Result, Schema } from "effect";
5
+ import { Digest } from "effect/crypto";
6
6
 
7
7
  // src/ImageCacheKey.ts
8
8
  /**
@@ -23,8 +23,9 @@ var ImageCacheKey = class ImageCacheKey extends Schema.Class("ImageCacheKey")({
23
23
  *
24
24
  * @remarks
25
25
  * `params` are encoded through `schema`, so a transformation participates and the key reflects the wire form. The
26
- * digest is core `Crypto`'s SHA-256, so `Crypto` is required — Node apps get it from `NodeServices.layer` or
27
- * `NodeCrypto.layer`.
26
+ * digest is core `Digest`'s SHA-256, so `Digest.Digest` is required — provide `Digest.layerWebCrypto` from
27
+ * `effect/crypto`, or a platform family layer such as `NodeCrypto.layerDigest`. `NodeServices.layer` does not
28
+ * include it.
28
29
  */
29
30
  static fromParams(schema, params, options) {
30
31
  return Effect.gen(function* () {
@@ -38,13 +39,9 @@ var ImageCacheKey = class ImageCacheKey extends Schema.Class("ImageCacheKey")({
38
39
  reason: "non-json",
39
40
  detail: canonical.failure
40
41
  });
41
- const bytes = yield* (yield* Crypto.Crypto).digest("SHA-256", new TextEncoder().encode(`${options.salt}\u0000${canonical.success}`)).pipe(Effect.mapError((cause) => new ImageCacheKeyError({
42
- reason: "digest",
43
- detail: cause.message,
44
- cause
45
- })));
42
+ const hex = yield* (yield* Digest.Digest).digestHex(Digest.sha256, new TextEncoder().encode(`${options.salt}\u0000${canonical.success}`));
46
43
  return ImageCacheKey.make({
47
- digest: Hex.encode(bytes),
44
+ digest: hex,
48
45
  salt: options.salt,
49
46
  namespace: options.namespace
50
47
  });
@@ -6,20 +6,17 @@ import { Schema } from "effect";
6
6
  *
7
7
  * @remarks
8
8
  * `encode`: the parameter schema rejected the params. `non-json`: the encoded form holds a value canonical JSON
9
- * cannot carry (a `Date`, a `bigint`, a non-finite number, a class instance). `digest`: the `Crypto` service failed.
9
+ * cannot carry (a `Date`, a `bigint`, a non-finite number, a class instance). The SHA-256 digest itself has no typed
10
+ * failure, so it is not a reason.
10
11
  *
11
12
  * @public
12
13
  */
13
14
  var ImageCacheKeyError = class extends Schema.TaggedError()("ImageCacheKeyError", {
14
15
  /** Which step failed. */
15
- reason: Schema.Literals([
16
- "encode",
17
- "non-json",
18
- "digest"
19
- ]),
16
+ reason: Schema.Literals(["encode", "non-json"]),
20
17
  /** What exactly was wrong. */
21
18
  detail: Schema.String,
22
- /** The schema error (`encode`) or platform error (`digest`). */
19
+ /** The schema error (`encode`). */
23
20
  cause: Schema.optionalKey(Schema.Defect())
24
21
  }) {
25
22
  get message() {
package/README.md CHANGED
@@ -8,10 +8,10 @@
8
8
  Image facts from bytes, and a cache for generated images. `ImageFacts` reads the format, MIME type and pixel dimensions of a PNG, JPEG, GIF, WebP or AVIF file straight from its header, with one typed failure for bytes that are not a readable image. `ImageCache` answers "have I already generated an image from these parameters?", so a build stops re-running an expensive renderer such as an Open Graph card generator on every run.
9
9
 
10
10
  > **Pre-`1.0.0`.** This package is part of the `@effected/*` kit, built on stable
11
- > Effect v4 (`effect` `^4.0.0`) and still in `0.x` development. Stable Effect
11
+ > Effect v4 (`effect` `~4.1.0`) and still in `0.x` development. Stable Effect
12
12
  > makes a kit `1.0.0` possible, not automatic. To keep your `effect` and
13
13
  > `@effect/*` versions on the line the kit is built and tested against, install
14
- > [`@effected/pnpm-plugin-effect`](https://www.npmjs.com/package/@effected/pnpm-plugin-effect).
14
+ > [`@effected/pnpm-plugin-effected`](https://www.npmjs.com/package/@effected/pnpm-plugin-effected).
15
15
  >
16
16
  > **Stability: unstable.** This package's API surface is not yet considered
17
17
  > complete and may change across `0.x` releases. Pin an exact version — even a
@@ -66,7 +66,7 @@ const facts = ImageFacts.fromBytes(bytes).pipe(
66
66
 
67
67
  ```ts
68
68
  import { ImageBackend, ImageCache, ImageCacheKey } from "@effected/images/cache";
69
- import { NodeServices } from "@effect/platform-node";
69
+ import { NodeCrypto, NodeServices } from "@effect/platform-node";
70
70
  import { Effect, Layer, Schema } from "effect";
71
71
 
72
72
  const CardParams = Schema.Struct({ title: Schema.String, theme: Schema.String });
@@ -89,7 +89,10 @@ const program = Effect.gen(function* () {
89
89
  { accept: ["png"] },
90
90
  );
91
91
  return { bytes, width: facts.width, hit };
92
- }).pipe(Effect.provide(CacheLive), Effect.provide(NodeServices.layer));
92
+ }).pipe(
93
+ Effect.provide(CacheLive),
94
+ Effect.provide(Layer.mergeAll(NodeServices.layer, NodeCrypto.layerDigest)),
95
+ );
93
96
  ```
94
97
 
95
98
  `getOrGenerate` returns the bytes, their `ImageFacts` and whether it was a `hit`. With `accept`, the result's `facts.format` is typed as the accepted formats, so `["png", "jpeg", "webp"]` gives `"png" | "jpeg" | "webp"`; without it, every format. A stored entry that no longer parses, or whose format is outside `accept`, is treated as a miss and overwritten. A generator result that is empty, unparseable or outside `accept` fails with `ImageGenerateError` and is never stored. Backend failures surface as `ImageBackendError`; the generator's own error passes through untouched.
@@ -120,7 +123,7 @@ declare const cachingEnabled: boolean;
120
123
  const backend = cachingEnabled ? ImageBackend.layerDirectory({ directory: ".cache/og" }) : ImageBackend.layerNone;
121
124
  ```
122
125
 
123
- The key digest uses core `Crypto`, and the directory backend uses `FileSystem` and `Path`. On Node, `NodeServices.layer` from `@effect/platform-node` provides all three.
126
+ The key digest uses core `Digest.Digest` (`effect/crypto`), and the directory backend uses `FileSystem` and `Path`. On Node, `NodeServices.layer` from `@effect/platform-node` provides `FileSystem` and `Path`, and `NodeCrypto.layerDigest` provides `Digest.Digest`; `Digest.layerWebCrypto` from `effect/crypto` works on any runtime with WebCrypto.
124
127
 
125
128
  ### Bring your own store
126
129
 
package/cache.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { Context, Crypto, Effect, FileSystem, Layer, Option, Path, Schema } from "effect";
1
+ import { Context, Effect, FileSystem, Layer, Option, Path, Schema } from "effect";
2
2
  import * as Images from "@effected/images";
3
+ import { Digest } from "effect/crypto";
3
4
  declare const ImageBackendError_base: Schema.Class<ImageBackendError, Schema.TaggedStruct<"ImageBackendError", {
4
5
  /** The backend operation that failed. */
5
6
  readonly operation: Schema.Literals<readonly ["get", "set"]>;
@@ -119,10 +120,10 @@ export declare class ImageBackend extends ImageBackend_base {
119
120
  }
120
121
  declare const ImageCacheKeyError_base: Schema.Class<ImageCacheKeyError, Schema.TaggedStruct<"ImageCacheKeyError", {
121
122
  /** Which step failed. */
122
- readonly reason: Schema.Literals<readonly ["encode", "non-json", "digest"]>;
123
+ readonly reason: Schema.Literals<readonly ["encode", "non-json"]>;
123
124
  /** What exactly was wrong. */
124
125
  readonly detail: Schema.String;
125
- /** The schema error (`encode`) or platform error (`digest`). */
126
+ /** The schema error (`encode`). */
126
127
  readonly cause: Schema.optionalKey<Schema.Defect>;
127
128
  }>, import("effect/Cause").YieldableError>;
128
129
  /**
@@ -130,7 +131,8 @@ declare const ImageCacheKeyError_base: Schema.Class<ImageCacheKeyError, Schema.T
130
131
  *
131
132
  * @remarks
132
133
  * `encode`: the parameter schema rejected the params. `non-json`: the encoded form holds a value canonical JSON
133
- * cannot carry (a `Date`, a `bigint`, a non-finite number, a class instance). `digest`: the `Crypto` service failed.
134
+ * cannot carry (a `Date`, a `bigint`, a non-finite number, a class instance). The SHA-256 digest itself has no typed
135
+ * failure, so it is not a reason.
134
136
  *
135
137
  * @public
136
138
  */
@@ -167,10 +169,11 @@ export declare class ImageCacheKey extends ImageCacheKey_base {
167
169
  *
168
170
  * @remarks
169
171
  * `params` are encoded through `schema`, so a transformation participates and the key reflects the wire form. The
170
- * digest is core `Crypto`'s SHA-256, so `Crypto` is required — Node apps get it from `NodeServices.layer` or
171
- * `NodeCrypto.layer`.
172
+ * digest is core `Digest`'s SHA-256, so `Digest.Digest` is required — provide `Digest.layerWebCrypto` from
173
+ * `effect/crypto`, or a platform family layer such as `NodeCrypto.layerDigest`. `NodeServices.layer` does not
174
+ * include it.
172
175
  */
173
- static fromParams<S extends Schema.ConstraintEncoder<unknown>>(schema: S, params: S["Type"], options: ImageCacheKeyOptions): Effect.Effect<ImageCacheKey, ImageCacheKeyError, Crypto.Crypto>;
176
+ static fromParams<S extends Schema.ConstraintEncoder<unknown>>(schema: S, params: S["Type"], options: ImageCacheKeyOptions): Effect.Effect<ImageCacheKey, ImageCacheKeyError, Digest.Digest>;
174
177
  }
175
178
  declare const ImageGenerateError_base: Schema.Class<ImageGenerateError, Schema.TaggedStruct<"ImageGenerateError", {
176
179
  /** Why the output was refused. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/images",
3
- "version": "0.6.2",
3
+ "version": "0.8.0",
4
4
  "private": false,
5
5
  "description": "Image facts (format, MIME type, dimensions) from bytes, and a generated-image cache, for Effect.",
6
6
  "keywords": [
@@ -45,7 +45,7 @@
45
45
  "./package.json": "./package.json"
46
46
  },
47
47
  "peerDependencies": {
48
- "effect": "^4.0.0"
48
+ "effect": "~4.1.0"
49
49
  },
50
50
  "engines": {
51
51
  "node": ">=24.11.0"
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.59.4"
8
+ "packageVersion": "7.60.0"
9
9
  }
10
10
  ]
11
11
  }