@effected/images 0.6.0 → 0.6.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.
@@ -1,11 +1,7 @@
1
+ import { causeMessage } from "./internal/causeMessage.js";
1
2
  import { Schema } from "effect";
2
3
 
3
4
  // src/ImageBackendError.ts
4
- const causeMessage = (cause) => {
5
- let current = cause;
6
- for (let depth = 0; depth < 8 && current instanceof Error && current.cause instanceof Error; depth++) current = current.cause;
7
- return current instanceof Error ? current.message : String(current);
8
- };
9
5
  /**
10
6
  * An image backend read or write failed.
11
7
  *
@@ -33,7 +29,9 @@ var ImageBackendError = class extends Schema.TaggedError()("ImageBackendError",
33
29
  cause: Schema.Defect()
34
30
  }) {
35
31
  get message() {
36
- return `Image backend ${this.operation} failed for key "${this.key}" (${this.reason}): ${causeMessage(this.cause)}`;
32
+ const summary = `Image backend ${this.operation} failed for key "${this.key}" (${this.reason})`;
33
+ const detail = causeMessage(this.cause);
34
+ return detail === void 0 ? summary : `${summary}: ${detail}`;
37
35
  }
38
36
  };
39
37
 
@@ -0,0 +1,39 @@
1
+ import { Predicate } from "effect";
2
+
3
+ // src/internal/causeMessage.ts
4
+ /** How many nodes of a cause chain the walk reads before stopping, so a cyclic chain cannot spin. */
5
+ const CAUSE_DEPTH = 8;
6
+ /** The message a single node carries: a thrown string, or a non-empty string `message` property. */
7
+ const messageAt = (node) => {
8
+ const text = Predicate.isString(node) ? node : Predicate.hasProperty(node, "message") && Predicate.isString(node.message) ? node.message : void 0;
9
+ return text === void 0 || text.trim() === "" ? void 0 : text;
10
+ };
11
+ /**
12
+ * Every distinct non-empty message a preserved cause chain carries, nearest
13
+ * first and joined with `: `, or `undefined` when nothing along it has one.
14
+ *
15
+ * A `Schema.Defect()` field holds whatever was thrown, so the read is guarded
16
+ * rather than assumed: `Predicate.hasProperty` + `Predicate.isString` accepts
17
+ * an `Error`, a cross-realm `Error` that fails `instanceof`, a plain
18
+ * `{ message }` object and a thrown string alike. An empty or whitespace-only
19
+ * message counts as none. The walk follows `cause` links because a wrapper's
20
+ * text is often the generic summary and the driver's text underneath is the
21
+ * actionable detail, yet a wrapper that composes its own context must not
22
+ * lose it either; so nothing is dropped, and a deeper text the nearer one
23
+ * already contains is not repeated. The walk is bounded, so a cycle terminates.
24
+ */
25
+ const causeMessage = (cause) => {
26
+ let message;
27
+ let node = cause;
28
+ for (let depth = 0; depth < CAUSE_DEPTH && node !== void 0 && node !== null; depth++) {
29
+ const text = messageAt(node);
30
+ if (text !== void 0) {
31
+ if (message === void 0 || text.includes(message)) message = text;
32
+ else if (!message.includes(text)) message = `${message}: ${text}`;
33
+ }
34
+ node = Predicate.hasProperty(node, "cause") ? node.cause : void 0;
35
+ }
36
+ return message;
37
+ };
38
+
39
+ export { causeMessage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/images",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
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": [