@ultimat3/storage 5.0.1 → 7.0.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/README.md +11 -8
- package/package.json +2 -2
- package/src/image.ts +6 -13
- package/src/index.ts +0 -1
package/README.md
CHANGED
|
@@ -235,7 +235,7 @@ Inside `pending/` deliberately: an upload nobody ever scanned is still an orphan
|
|
|
235
235
|
| `X_STORAGE_QUARANTINED` | `promoteAttachment` on a key nothing has released from `pending/quarantine/` |
|
|
236
236
|
| `X_NOT_IMPLEMENTED` | S3 user metadata / cache-control; `serverSideEncryption` on either driver |
|
|
237
237
|
| `X_ENV_MISSING` | core's: S3 credential env vars, or a `localDriver` built outside development where neither `signingSecret` nor `STORAGE_SIGNING_SECRET` holds a secret other than the published `DEV_SIGNING_SECRET` |
|
|
238
|
-
| `X_IMAGE_UNSUPPORTED` | core's: an `avif
|
|
238
|
+
| `X_IMAGE_UNSUPPORTED` | core's: an `avif` encode, or a source no built-in decoder reads |
|
|
239
239
|
| `X_IMAGE_DECODE_FAILED` | core's: truncated or corrupt image bytes |
|
|
240
240
|
|
|
241
241
|
## Images
|
|
@@ -243,11 +243,14 @@ Inside `pending/` deliberately: an upload nobody ever scanned is still an orphan
|
|
|
243
243
|
`variantKey()`, `srcsetDescriptors()`, `fitDimensions()` are pure — `@ultimat3/seo` builds
|
|
244
244
|
`srcset` from them without decoding a byte.
|
|
245
245
|
|
|
246
|
-
`transformImage()` and `blurPlaceholder()` are real, over `@ultimat3/core`'s
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
246
|
+
`transformImage()` and `blurPlaceholder()` are real, over `@ultimat3/core`'s pipeline, which is
|
|
247
|
+
`Bun.Image` — no `sharp`, no dependency. **It encodes `png`, `jpeg` and `webp`** — so the default
|
|
248
|
+
format and the default `.webp` key extension finally agree, and a `srcset` entry can be served
|
|
249
|
+
rather than only named. `avif` remains key and `srcset` math: it needs an OS codec the portable
|
|
250
|
+
backend never uses, so asking for its bytes rejects with core's `X_IMAGE_UNSUPPORTED` naming the
|
|
251
|
+
three that work; produce it through a CDN or a custom `ImageTransformDriver`. `png` and `webp` are
|
|
252
|
+
the outputs that keep alpha. The encoded size is always exactly `fitDimensions()`, so the
|
|
253
|
+
`width`/`height` `@ultimat3/seo` already wrote into the tag match the bytes — `contain` fits inside
|
|
254
|
+
the box, it does not letterbox to it. `blurPlaceholder()` returns a ThumbHash PNG `data:` URI, at
|
|
255
|
+
most 32px on its long edge.
|
|
253
256
|
`bun test` from `packages/storage`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/storage",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Named disks over Bun.file and Bun.s3: safe keys, signed URLs, sniffed uploads",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,6 +31,6 @@
|
|
|
31
31
|
"test": "bun test"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ultimat3/core": "
|
|
34
|
+
"@ultimat3/core": "7.0.0"
|
|
35
35
|
}
|
|
36
36
|
}
|
package/src/image.ts
CHANGED
|
@@ -3,12 +3,7 @@
|
|
|
3
3
|
// `<img srcset>` from `srcsetDescriptors()` without decoding a byte, and when it does need the
|
|
4
4
|
// bytes, `transformImage()` returns exactly the size `fitDimensions()` already promised.
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
blurDataUrl,
|
|
8
|
-
BLUR_PLACEHOLDER_WIDTH as CORE_BLUR_PLACEHOLDER_WIDTH,
|
|
9
|
-
probeImage,
|
|
10
|
-
transformImageBytes,
|
|
11
|
-
} from '@ultimat3/core';
|
|
6
|
+
import { blurDataUrl, probeImage, transformImageBytes } from '@ultimat3/core';
|
|
12
7
|
import { assertSafeKey, keyExtname } from './path';
|
|
13
8
|
|
|
14
9
|
export const IMAGE_FORMATS = ['avif', 'webp', 'jpeg', 'png'] as const;
|
|
@@ -33,8 +28,6 @@ export interface ImageSize {
|
|
|
33
28
|
|
|
34
29
|
export const DEFAULT_QUALITY = 80;
|
|
35
30
|
export const DEFAULT_SRCSET_WIDTHS = [320, 640, 960, 1280, 1920] as const;
|
|
36
|
-
/** Small enough to inline in HTML; big enough to blur convincingly. Core owns the number. */
|
|
37
|
-
export const BLUR_PLACEHOLDER_WIDTH = CORE_BLUR_PLACEHOLDER_WIDTH;
|
|
38
31
|
|
|
39
32
|
const FORMAT_EXTENSIONS: Readonly<Record<ImageFormat, string>> = {
|
|
40
33
|
avif: 'avif',
|
|
@@ -116,10 +109,10 @@ export function fitDimensions(source: ImageSize, transform: ImageTransform): Ima
|
|
|
116
109
|
}
|
|
117
110
|
|
|
118
111
|
/**
|
|
119
|
-
* Decode, resize, encode — core's pipeline, which encodes **png and
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* CDN or a custom `ImageTransformDriver`.
|
|
112
|
+
* Decode, resize, encode — core's pipeline, which encodes **png, jpeg and webp**. `avif` stays
|
|
113
|
+
* key/`srcset` math: asking for its bytes rejects with core's `X_IMAGE_UNSUPPORTED` (not
|
|
114
|
+
* re-wrapped — one failure, one code) because it needs an OS codec the portable backend never
|
|
115
|
+
* uses, and producing it means a CDN or a custom `ImageTransformDriver`.
|
|
123
116
|
*
|
|
124
117
|
* The output box is `fitDimensions()`, always: that is the size `@ultimat3/seo` has already
|
|
125
118
|
* written into the `<img>` tag, and bytes that disagreed with it would be the layout shift
|
|
@@ -144,5 +137,5 @@ export async function transformImage(
|
|
|
144
137
|
|
|
145
138
|
/** A `data:` URI small enough to inline as the LQIP behind a real image. Always PNG. */
|
|
146
139
|
export async function blurPlaceholder(bytes: Uint8Array): Promise<string> {
|
|
147
|
-
return blurDataUrl(bytes
|
|
140
|
+
return blurDataUrl(bytes);
|
|
148
141
|
}
|