@effected/images 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/ImageCacheKey.js +7 -10
- package/ImageCacheKeyError.js +4 -7
- package/README.md +8 -5
- package/cache.d.ts +10 -7
- package/package.json +2 -2
- package/tsdoc-metadata.json +1 -1
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 {
|
|
5
|
-
import
|
|
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 `
|
|
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
|
|
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:
|
|
44
|
+
digest: hex,
|
|
48
45
|
salt: options.salt,
|
|
49
46
|
namespace: options.namespace
|
|
50
47
|
});
|
package/ImageCacheKeyError.js
CHANGED
|
@@ -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).
|
|
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`)
|
|
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`
|
|
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-
|
|
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(
|
|
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 `
|
|
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,
|
|
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"
|
|
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`)
|
|
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).
|
|
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 `
|
|
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,
|
|
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.
|
|
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": "
|
|
48
|
+
"effect": "~4.1.0"
|
|
49
49
|
},
|
|
50
50
|
"engines": {
|
|
51
51
|
"node": ">=24.11.0"
|