@adonis-agora/media 0.19.0 → 0.20.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.
@@ -11,7 +11,7 @@
11
11
  rel="stylesheet"
12
12
  />
13
13
  <title>Media · Agora</title>
14
- <script type="module" crossorigin src="/__MEDIA_DASHBOARD__/assets/index-3HWw8Zsr.js"></script>
14
+ <script type="module" crossorigin src="/__MEDIA_DASHBOARD__/assets/index-BO6hgGp1.js"></script>
15
15
  <link rel="stylesheet" crossorigin href="/__MEDIA_DASHBOARD__/assets/index-CrdjxPM5.css">
16
16
  </head>
17
17
  <body>
@@ -5,6 +5,11 @@ export interface ConversionPreset {
5
5
  fit?: 'cover' | 'contain' | 'fill' | 'inside' | 'outside';
6
6
  format?: 'jpeg' | 'png' | 'webp' | 'avif';
7
7
  quality?: number;
8
+ /**
9
+ * Gaussian blur sigma (sharp's `blur(sigma)`, 0.3–1000), applied after the resize. Pair it with a
10
+ * small `width` for a blurred low-res variant served as a file.
11
+ */
12
+ blur?: number;
8
13
  /** Generate eagerly on attach instead of lazily on first access. */
9
14
  eager?: boolean;
10
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"image_processor.d.ts","sourceRoot":"","sources":["../../src/image_processor.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,+FAA+F;AAC/F,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC7E"}
1
+ {"version":3,"file":"image_processor.d.ts","sourceRoot":"","sources":["../../src/image_processor.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,+FAA+F;AAC/F,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC7E"}
@@ -43,6 +43,8 @@ export { createMediaTables, dropMediaTables } from './stores/lucid-schema.js';
43
43
  export type { Transformer, TransformerContext, TransformerWriteOptions, TransformResult, } from './transformer.js';
44
44
  export type { HlsRemuxEngine, HlsRemuxRequest, HlsRemuxSummary, HlsTransformerOptions, WebCodecsProvider, WebCodecsSupport, } from './transformers/hls.js';
45
45
  export { HLS_ENTRY_PLAYLIST, HlsTransformer, resolveWebCodecsSupport } from './transformers/hls.js';
46
+ export type { ImagePlaceholder, PlaceholderEngine, PlaceholderOptions, PlaceholderTransformerOptions, } from './transformers/placeholder.js';
47
+ export { PlaceholderTransformer, placeholderOf } from './transformers/placeholder.js';
46
48
  export type { MediaProbeEngine, MediaProbeSummary, MetadataProbeTransformerOptions, } from './transformers/probe.js';
47
49
  export { MetadataProbeTransformer } from './transformers/probe.js';
48
50
  export type { TusRequest, TusResponse, TusUploadHandlerOptions } from './tus.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/dist/src/index.js CHANGED
@@ -37,6 +37,7 @@ export { StorageManager } from './storage_manager.js';
37
37
  // Schema helpers (ecosystem convention — lib owns its own schema; see `stores/lucid-schema.ts`)
38
38
  export { createMediaTables, dropMediaTables } from './stores/lucid-schema.js';
39
39
  export { HLS_ENTRY_PLAYLIST, HlsTransformer, resolveWebCodecsSupport } from './transformers/hls.js';
40
+ export { PlaceholderTransformer, placeholderOf } from './transformers/placeholder.js';
40
41
  export { MetadataProbeTransformer } from './transformers/probe.js';
41
42
  export { parseTusMetadata, TUS_VERSION, TusUploadHandler } from './tus.js';
42
43
  // Direct-S3 upload modes (proxy + direct multipart)
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import type { ConversionPreset, ConversionResult, ImageProcessor } from '../image_processor.js';
2
2
  /**
3
- * `ImageProcessor` backed by [sharp](https://sharp.pixelplumbing.com). Resize/crop via `fit`,
4
- * convert format, and apply quality. The default output format is `webp`. Import this directly
3
+ * `ImageProcessor` backed by [sharp](https://sharp.pixelplumbing.com). Auto-orients from EXIF,
4
+ * resizes/crops via `fit`, optionally blurs, converts format, and applies quality. The default output format is `webp`. Import this directly
5
5
  * (`@adonis-agora/media/processors/sharp`) or select it lazily with `processors.sharp()` in config.
6
6
  */
7
7
  export declare class SharpImageProcessor implements ImageProcessor {
@@ -1 +1 @@
1
- {"version":3,"file":"sharp.d.ts","sourceRoot":"","sources":["../../../src/processors/sharp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAShG;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,cAAc;IAClD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgBhF;CACF"}
1
+ {"version":3,"file":"sharp.d.ts","sourceRoot":"","sources":["../../../src/processors/sharp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAShG;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,cAAc;IAClD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAoBhF;CACF"}
@@ -6,13 +6,15 @@ const CONTENT_TYPE = {
6
6
  avif: 'image/avif',
7
7
  };
8
8
  /**
9
- * `ImageProcessor` backed by [sharp](https://sharp.pixelplumbing.com). Resize/crop via `fit`,
10
- * convert format, and apply quality. The default output format is `webp`. Import this directly
9
+ * `ImageProcessor` backed by [sharp](https://sharp.pixelplumbing.com). Auto-orients from EXIF,
10
+ * resizes/crops via `fit`, optionally blurs, converts format, and applies quality. The default output format is `webp`. Import this directly
11
11
  * (`@adonis-agora/media/processors/sharp`) or select it lazily with `processors.sharp()` in config.
12
12
  */
13
13
  export class SharpImageProcessor {
14
14
  async convert(input, preset) {
15
- let pipeline = sharp(input);
15
+ // `rotate()` with no angle applies the EXIF orientation — without it a portrait phone photo
16
+ // comes out sideways, since the output drops the EXIF tag that made it display upright.
17
+ let pipeline = sharp(input).rotate();
16
18
  if (preset.width || preset.height) {
17
19
  pipeline = pipeline.resize({
18
20
  ...(preset.width ? { width: preset.width } : {}),
@@ -20,6 +22,8 @@ export class SharpImageProcessor {
20
22
  fit: preset.fit ?? 'cover',
21
23
  });
22
24
  }
25
+ if (preset.blur)
26
+ pipeline = pipeline.blur(preset.blur);
23
27
  const format = preset.format ?? 'webp';
24
28
  pipeline = pipeline.toFormat(format, preset.quality ? { quality: preset.quality } : {});
25
29
  const data = await pipeline.toBuffer();
@@ -1 +1 @@
1
- {"version":3,"file":"sharp.js","sourceRoot":"","sources":["../../../src/processors/sharp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAC9B,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,MAAwB;QACnD,IAAI,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAE5B,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;gBACzB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChD,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnD,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,OAAO;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;QACvC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAExF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACvC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,0BAA0B,EAAE,CAAC;IAC3F,CAAC;CACF"}
1
+ {"version":3,"file":"sharp.js","sourceRoot":"","sources":["../../../src/processors/sharp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,YAAY,GAA2B;IAC3C,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAC9B,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,MAAwB;QACnD,4FAA4F;QAC5F,wFAAwF;QACxF,IAAI,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAErC,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;gBACzB,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChD,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnD,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,OAAO;aAC3B,CAAC,CAAC;QACL,CAAC;QAED,IAAI,MAAM,CAAC,IAAI;YAAE,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEvD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;QACvC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAExF,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACvC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,0BAA0B,EAAE,CAAC;IAC3F,CAAC;CACF"}
@@ -1,4 +1,5 @@
1
1
  import { MediaManager } from './media_manager.js';
2
+ import { type ImagePlaceholder } from './transformers/placeholder.js';
2
3
  /**
3
4
  * Store a single file for an owner and return stable public URLs. This is a thin, generic seam over
4
5
  * {@link MediaManager} for callers (e.g. another Agora package storing an avatar) that only need to
@@ -21,6 +22,14 @@ export interface StoredSingleFile {
21
22
  url: string;
22
23
  /** Public URL of the `thumb` conversion, or `null` when that conversion isn't configured. */
23
24
  thumbUrl: string | null;
25
+ /** Id of the stored media record — keep it to look the record up later without the owner. */
26
+ id: string;
27
+ /**
28
+ * The blur-up placeholder from a `transformers.placeholder()` on the collection
29
+ * (`{ dataUrl, width, height, color }`), or `null` when none is configured or it was skipped.
30
+ * Persist it next to the URL to paint a preview without a media lookup at render time.
31
+ */
32
+ placeholder: ImagePlaceholder | null;
24
33
  }
25
34
  export interface RemoveSingleFileInput {
26
35
  ownerType: string;
@@ -59,4 +68,6 @@ export declare function removeSingleFile(input: RemoveSingleFileInput): Promise<
59
68
  * container. Callers use this to feature-detect media before routing a store through it.
60
69
  */
61
70
  export declare function isSingleFileStoreAvailable(): Promise<boolean>;
71
+ export type { ImagePlaceholder } from './transformers/placeholder.js';
72
+ export { placeholderOf } from './transformers/placeholder.js';
62
73
  //# sourceMappingURL=single_file_store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"single_file_store.d.ts","sourceRoot":"","sources":["../../src/single_file_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,6FAA6F;IAC7F,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CAoB3B;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAG5F;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlF;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,OAAO,CAAC,CAEnE"}
1
+ {"version":3,"file":"single_file_store.d.ts","sourceRoot":"","sources":["../../src/single_file_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,KAAK,gBAAgB,EAAiB,MAAM,+BAA+B,CAAC;AAErF;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,6FAA6F;IAC7F,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,6FAA6F;IAC7F,EAAE,EAAE,MAAM,CAAC;IACX;;;;OAIG;IACH,WAAW,EAAE,gBAAgB,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CAoB3B;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAG5F;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlF;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,OAAO,CAAC,CAEnE;AAED,YAAY,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { MediaManager } from './media_manager.js';
2
2
  import { getBootedApp } from './services/booted_app.js';
3
+ import { placeholderOf } from './transformers/placeholder.js';
3
4
  /**
4
5
  * Core of {@link storeSingleFile} driven by an explicit {@link MediaManager}, so tests can exercise
5
6
  * it with an in-memory manager without booting an app. Attaches the file to the owner's collection
@@ -23,7 +24,7 @@ export async function storeSingleFileWith(manager, input) {
23
24
  catch {
24
25
  thumbUrl = null;
25
26
  }
26
- return { url, thumbUrl };
27
+ return { url, thumbUrl, id: record.id, placeholder: placeholderOf(record) };
27
28
  }
28
29
  /**
29
30
  * Core of {@link removeSingleFile} driven by an explicit {@link MediaManager}. Empties the owner's
@@ -62,4 +63,5 @@ export async function removeSingleFile(input) {
62
63
  export async function isSingleFileStoreAvailable() {
63
64
  return getBootedApp().container.hasBinding(MediaManager);
64
65
  }
66
+ export { placeholderOf } from './transformers/placeholder.js';
65
67
  //# sourceMappingURL=single_file_store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"single_file_store.js","sourceRoot":"","sources":["../../src/single_file_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAiCxD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAqB,EACrB,KAA2B;IAE3B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QAC9E,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAEjD,0FAA0F;IAC1F,6FAA6F;IAC7F,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAqB,EACrB,KAA4B;IAE5B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACjG,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAA2B;IAC/D,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClE,OAAO,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAA4B;IACjE,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClE,OAAO,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAC9C,OAAO,YAAY,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAC3D,CAAC"}
1
+ {"version":3,"file":"single_file_store.js","sourceRoot":"","sources":["../../src/single_file_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAyB,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAyCrF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAqB,EACrB,KAA2B;IAE3B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;QAC9E,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACzB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAEjD,0FAA0F;IAC1F,6FAA6F;IAC7F,IAAI,QAAQ,GAAkB,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAqB,EACrB,KAA4B;IAE5B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACjG,KAAK,MAAM,MAAM,IAAI,OAAO;QAAE,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAA2B;IAC/D,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClE,OAAO,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAA4B;IACjE,MAAM,OAAO,GAAG,MAAM,YAAY,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClE,OAAO,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B;IAC9C,OAAO,YAAY,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAC3D,CAAC;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { HlsTransformer, type HlsTransformerOptions } from './hls.js';
2
+ import { PlaceholderTransformer, type PlaceholderTransformerOptions } from './placeholder.js';
2
3
  import { MetadataProbeTransformer, type MetadataProbeTransformerOptions } from './probe.js';
3
4
  /**
4
5
  * The transformer factory namespace used in `config/media.ts` — the {@link Transformer}
@@ -18,13 +19,18 @@ import { MetadataProbeTransformer, type MetadataProbeTransformerOptions } from '
18
19
  * })
19
20
  * ```
20
21
  *
21
- * Constructing a transformer here never loads its engine — the optional `mediabunny` peer is
22
- * imported inside the first `transform()` call, so config stays side-effect-free.
22
+ * Constructing a transformer here never loads its engine — the optional `mediabunny` / `sharp`
23
+ * peers are imported inside the first `transform()` call, so config stays side-effect-free.
23
24
  */
24
25
  export declare const transformers: {
25
26
  /** Video → HLS package (MPEG-TS segments + playlists) via mediabunny. Default name `'hls'`. */
26
27
  hls<Name extends string = 'hls'>(options?: HlsTransformerOptions<Name>): HlsTransformer<Name>;
27
28
  /** Metadata-only probe (duration/resolution/codecs) via mediabunny. Default name `'probe'`. */
28
29
  probe<Name extends string = 'probe'>(options?: MetadataProbeTransformerOptions<Name>): MetadataProbeTransformer<Name>;
30
+ /**
31
+ * Image → inline blurred-preview metadata (tiny WebP `dataUrl`, dimensions, dominant colour) via
32
+ * sharp. Eager by default. Default name `'placeholder'`.
33
+ */
34
+ placeholder<Name extends string = 'placeholder'>(options?: PlaceholderTransformerOptions<Name>): PlaceholderTransformer<Name>;
29
35
  };
30
36
  //# sourceMappingURL=factory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/transformers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,KAAK,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY;IACvB,+FAA+F;IAC/F,GAAG,CAAC,IAAI,SAAS,MAAM,GAAG,KAAK,YAAW,qBAAqB,CAAC,IAAI,CAAC;IAGrE,+FAA+F;IAC/F,KAAK,CAAC,IAAI,SAAS,MAAM,GAAG,OAAO,YAAW,+BAA+B,CAAC,IAAI,CAAC;CAGpF,CAAC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/transformers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,KAAK,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EAAE,wBAAwB,EAAE,KAAK,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY;IACvB,+FAA+F;IAC/F,GAAG,CAAC,IAAI,SAAS,MAAM,GAAG,KAAK,YAAW,qBAAqB,CAAC,IAAI,CAAC;IAGrE,+FAA+F;IAC/F,KAAK,CAAC,IAAI,SAAS,MAAM,GAAG,OAAO,YAAW,+BAA+B,CAAC,IAAI,CAAC;IAGnF;;;OAGG;IACH,WAAW,CAAC,IAAI,SAAS,MAAM,GAAG,aAAa,YACpC,6BAA6B,CAAC,IAAI,CAAC;CAI/C,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { HlsTransformer } from './hls.js';
2
+ import { PlaceholderTransformer } from './placeholder.js';
2
3
  import { MetadataProbeTransformer } from './probe.js';
3
4
  /**
4
5
  * The transformer factory namespace used in `config/media.ts` — the {@link Transformer}
@@ -18,8 +19,8 @@ import { MetadataProbeTransformer } from './probe.js';
18
19
  * })
19
20
  * ```
20
21
  *
21
- * Constructing a transformer here never loads its engine — the optional `mediabunny` peer is
22
- * imported inside the first `transform()` call, so config stays side-effect-free.
22
+ * Constructing a transformer here never loads its engine — the optional `mediabunny` / `sharp`
23
+ * peers are imported inside the first `transform()` call, so config stays side-effect-free.
23
24
  */
24
25
  export const transformers = {
25
26
  /** Video → HLS package (MPEG-TS segments + playlists) via mediabunny. Default name `'hls'`. */
@@ -30,5 +31,12 @@ export const transformers = {
30
31
  probe(options = {}) {
31
32
  return new MetadataProbeTransformer(options);
32
33
  },
34
+ /**
35
+ * Image → inline blurred-preview metadata (tiny WebP `dataUrl`, dimensions, dominant colour) via
36
+ * sharp. Eager by default. Default name `'placeholder'`.
37
+ */
38
+ placeholder(options = {}) {
39
+ return new PlaceholderTransformer(options);
40
+ },
33
41
  };
34
42
  //# sourceMappingURL=factory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/transformers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA8B,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAwC,MAAM,YAAY,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,+FAA+F;IAC/F,GAAG,CAA8B,OAAO,GAAgC,EAAE;QACxE,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IACD,+FAA+F;IAC/F,KAAK,CAAgC,OAAO,GAA0C,EAAE;QACtF,OAAO,IAAI,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/transformers/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA8B,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAsC,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EAAE,wBAAwB,EAAwC,MAAM,YAAY,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,+FAA+F;IAC/F,GAAG,CAA8B,OAAO,GAAgC,EAAE;QACxE,OAAO,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IACD,+FAA+F;IAC/F,KAAK,CAAgC,OAAO,GAA0C,EAAE;QACtF,OAAO,IAAI,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IACD;;;OAGG;IACH,WAAW,CACT,OAAO,GAAwC,EAAE;QAEjD,OAAO,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;CACF,CAAC"}
@@ -0,0 +1,85 @@
1
+ import type { MediaRecord } from '../media_record.js';
2
+ import type { Transformer, TransformerContext, TransformResult } from '../transformer.js';
3
+ /** What a placeholder run yields — persisted verbatim as the conversion's `meta`. */
4
+ export interface ImagePlaceholder {
5
+ /**
6
+ * A tiny (≤ `size` px on the long edge) WebP of the image, as a `data:` URL — typically a few
7
+ * hundred bytes. Inline it as the `<img>` background (or `src`) and blur it with CSS while the
8
+ * real image loads; no client-side decoder needed.
9
+ */
10
+ dataUrl: string;
11
+ /** Width of the original, after EXIF orientation. Use it with {@link height} to reserve layout. */
12
+ width: number;
13
+ /** Height of the original, after EXIF orientation. */
14
+ height: number;
15
+ /** Dominant colour as `#rrggbb` — a flat fallback for the placeholder. */
16
+ color: string;
17
+ }
18
+ export interface PlaceholderOptions {
19
+ /** Long edge of the tiny preview, in px. Default `16`. */
20
+ size: number;
21
+ /** WebP quality of the tiny preview. Default `50`. */
22
+ quality: number;
23
+ }
24
+ /**
25
+ * The engine seam of {@link PlaceholderTransformer}: image bytes in, placeholder out. The default
26
+ * engine is sharp (lazy); tests inject a fake.
27
+ */
28
+ export interface PlaceholderEngine {
29
+ generate(input: Uint8Array, options: PlaceholderOptions): Promise<ImagePlaceholder>;
30
+ }
31
+ export interface PlaceholderTransformerOptions<Name extends string = 'placeholder'> {
32
+ /** Conversion name on the record. Default `'placeholder'`. */
33
+ name?: Name;
34
+ /**
35
+ * Run inside attach. Default `true`: a placeholder is only useful if it exists by the time the
36
+ * image is first rendered, and generating one is a single small decode. It does read the whole
37
+ * original, though — on a remote disk (S3) that is a download per attach; set `false` and run
38
+ * `media.library.transform(id, name)` from a job if that matters more than having it at once.
39
+ */
40
+ eager?: boolean;
41
+ /** Long edge of the tiny preview, in px. Default `16` — bigger is sharper but heavier inline. */
42
+ size?: number;
43
+ /** WebP quality of the tiny preview (1–100). Default `50`. */
44
+ quality?: number;
45
+ /** Replace the sharp engine (mainly for tests). */
46
+ engine?: PlaceholderEngine;
47
+ }
48
+ /**
49
+ * The built-in **image placeholder** {@link Transformer} — a metadata-only transform: it writes no
50
+ * artifact, and persists on `record.conversions['placeholder'].meta` a tiny inline preview
51
+ * (`dataUrl`), the original's dimensions and its dominant colour. Everything a page needs to
52
+ * render a blurred LQIP with the right aspect ratio before the real image arrives, without a
53
+ * second request.
54
+ *
55
+ * ```ts
56
+ * // config/media.ts
57
+ * { name: 'avatar', acceptsMimeTypes: ['image/png', 'image/jpeg'], transformers: [transformers.placeholder()] }
58
+ *
59
+ * const record = await media.library.find(id)
60
+ * record.conversions.placeholder?.meta // { dataUrl: 'data:image/webp;base64,…', width, height, color }
61
+ * ```
62
+ *
63
+ * Eager by default. A record whose MIME type is not `image/*`, or is an SVG, is skipped (`meta: {}`) rather than
64
+ * failing the attach, so declaring it on a mixed collection (images + PDFs) is safe.
65
+ */
66
+ export declare class PlaceholderTransformer<Name extends string = 'placeholder'> implements Transformer {
67
+ readonly name: Name;
68
+ readonly eager: boolean;
69
+ private readonly options;
70
+ private readonly engine;
71
+ constructor(options?: PlaceholderTransformerOptions<Name>);
72
+ transform(context: TransformerContext): Promise<TransformResult>;
73
+ }
74
+ /**
75
+ * Read the blur-up placeholder off a record: the first conversion whose `meta` has the
76
+ * {@link ImagePlaceholder} shape, so a renamed transformer (`name: 'lqip'`) is found too. `null`
77
+ * when the collection has no placeholder transformer, it hasn't run, or it skipped a non-image.
78
+ *
79
+ * ```ts
80
+ * const record = await media.library.find(user.avatarMediaId)
81
+ * return { avatarUrl, avatarPlaceholder: record && placeholderOf(record) }
82
+ * ```
83
+ */
84
+ export declare function placeholderOf(record: MediaRecord): ImagePlaceholder | null;
85
+ //# sourceMappingURL=placeholder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"placeholder.d.ts","sourceRoot":"","sources":["../../../src/transformers/placeholder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE1F,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,mGAAmG;IACnG,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACrF;AAED,MAAM,WAAW,6BAA6B,CAAC,IAAI,SAAS,MAAM,GAAG,aAAa;IAChF,8DAA8D;IAC9D,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iGAAiG;IACjG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,sBAAsB,CAAC,IAAI,SAAS,MAAM,GAAG,aAAa,CAAE,YAAW,WAAW;IAC7F,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IAEvD,YAAY,OAAO,GAAE,6BAA6B,CAAC,IAAI,CAAM,EAK5D;IAEK,SAAS,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,eAAe,CAAC,CAQrE;CACF;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB,GAAG,IAAI,CAmB1E"}
@@ -0,0 +1,110 @@
1
+ import { TransformerRuntimeMissingError } from '../errors.js';
2
+ /**
3
+ * The built-in **image placeholder** {@link Transformer} — a metadata-only transform: it writes no
4
+ * artifact, and persists on `record.conversions['placeholder'].meta` a tiny inline preview
5
+ * (`dataUrl`), the original's dimensions and its dominant colour. Everything a page needs to
6
+ * render a blurred LQIP with the right aspect ratio before the real image arrives, without a
7
+ * second request.
8
+ *
9
+ * ```ts
10
+ * // config/media.ts
11
+ * { name: 'avatar', acceptsMimeTypes: ['image/png', 'image/jpeg'], transformers: [transformers.placeholder()] }
12
+ *
13
+ * const record = await media.library.find(id)
14
+ * record.conversions.placeholder?.meta // { dataUrl: 'data:image/webp;base64,…', width, height, color }
15
+ * ```
16
+ *
17
+ * Eager by default. A record whose MIME type is not `image/*`, or is an SVG, is skipped (`meta: {}`) rather than
18
+ * failing the attach, so declaring it on a mixed collection (images + PDFs) is safe.
19
+ */
20
+ export class PlaceholderTransformer {
21
+ name;
22
+ eager;
23
+ options;
24
+ engine;
25
+ constructor(options = {}) {
26
+ this.name = options.name ?? 'placeholder';
27
+ this.eager = options.eager ?? true;
28
+ this.options = { size: options.size ?? 16, quality: options.quality ?? 50 };
29
+ this.engine = options.engine;
30
+ }
31
+ async transform(context) {
32
+ // Vectors are skipped too: they render crisp at any size (nothing to blur up to), and an SVG
33
+ // without intrinsic dimensions makes sharp throw — which, eager, would roll back the attach.
34
+ const { mimeType } = context.record;
35
+ if (!mimeType.startsWith('image/') || mimeType.startsWith('image/svg'))
36
+ return { meta: {} };
37
+ const engine = this.engine ?? (await loadSharpPlaceholderEngine(this.name));
38
+ const placeholder = await engine.generate(await context.getBytes(), this.options);
39
+ return { meta: { ...placeholder } };
40
+ }
41
+ }
42
+ /**
43
+ * Read the blur-up placeholder off a record: the first conversion whose `meta` has the
44
+ * {@link ImagePlaceholder} shape, so a renamed transformer (`name: 'lqip'`) is found too. `null`
45
+ * when the collection has no placeholder transformer, it hasn't run, or it skipped a non-image.
46
+ *
47
+ * ```ts
48
+ * const record = await media.library.find(user.avatarMediaId)
49
+ * return { avatarUrl, avatarPlaceholder: record && placeholderOf(record) }
50
+ * ```
51
+ */
52
+ export function placeholderOf(record) {
53
+ for (const conversion of Object.values(record.conversions)) {
54
+ const meta = conversion.meta;
55
+ if (meta &&
56
+ typeof meta.dataUrl === 'string' &&
57
+ typeof meta.color === 'string' &&
58
+ Number.isFinite(meta.width) &&
59
+ Number.isFinite(meta.height)) {
60
+ return {
61
+ dataUrl: meta.dataUrl,
62
+ width: meta.width,
63
+ height: meta.height,
64
+ color: meta.color,
65
+ };
66
+ }
67
+ }
68
+ return null;
69
+ }
70
+ /** sharp-backed {@link PlaceholderEngine}, importing the optional peer on first use. */
71
+ async function loadSharpPlaceholderEngine(transformerName) {
72
+ let sharp;
73
+ try {
74
+ sharp = (await import('sharp')).default;
75
+ }
76
+ catch (error) {
77
+ // Only a missing `sharp` itself — a broken install missing a transitive dep must surface as is.
78
+ if (error.code === 'ERR_MODULE_NOT_FOUND' &&
79
+ error instanceof Error &&
80
+ error.message.includes("'sharp'")) {
81
+ throw new TransformerRuntimeMissingError(transformerName, "the optional peer dependency 'sharp'", 'Install it (`pnpm add sharp`) or inject a custom `engine`.');
82
+ }
83
+ throw error;
84
+ }
85
+ return {
86
+ async generate(input, { size, quality }) {
87
+ const image = sharp(input, { failOn: 'none' }).rotate();
88
+ const metadata = await image.metadata();
89
+ // `metadata()` reports the stored (pre-rotation) size; orientations 5–8 swap the axes.
90
+ const swap = (metadata.orientation ?? 1) >= 5;
91
+ const width = (swap ? metadata.height : metadata.width) ?? 0;
92
+ const height = (swap ? metadata.width : metadata.height) ?? 0;
93
+ const [{ dominant }, tiny] = await Promise.all([
94
+ image.clone().stats(),
95
+ image
96
+ .clone()
97
+ .resize(size, size, { fit: 'inside' })
98
+ .webp({ quality, alphaQuality: quality })
99
+ .toBuffer(),
100
+ ]);
101
+ return {
102
+ dataUrl: `data:image/webp;base64,${tiny.toString('base64')}`,
103
+ width,
104
+ height,
105
+ color: `#${[dominant.r, dominant.g, dominant.b].map((c) => c.toString(16).padStart(2, '0')).join('')}`,
106
+ };
107
+ },
108
+ };
109
+ }
110
+ //# sourceMappingURL=placeholder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"placeholder.js","sourceRoot":"","sources":["../../../src/transformers/placeholder.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adonis-agora/media",
3
- "version": "0.19.0",
4
- "description": "Media-library for AdonisJS — owner collections (MIME whitelist, single-file replace, ordering), image conversions (eager/lazy), pluggable content transformers (HLS video via mediabunny, metadata probe), and column attachments, all on top of @adonisjs/drive. Pluggable MediaStore (in-memory + Lucid) and ImageProcessor (sharp). Part of the Agora ecosystem.",
3
+ "version": "0.20.0",
4
+ "description": "Media-library for AdonisJS — owner collections (MIME whitelist, single-file replace, ordering), image conversions (eager/lazy), pluggable content transformers (HLS video via mediabunny, metadata probe, image blur-up placeholder), and column attachments, all on top of @adonisjs/drive. Pluggable MediaStore (in-memory + Lucid) and ImageProcessor (sharp). Part of the Agora ecosystem.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -148,23 +148,23 @@
148
148
  "devDependencies": {
149
149
  "@adonis-agora/media-dashboard": "9.0.0",
150
150
  "@adonis-agora/media-react": "0.6.0",
151
- "@adonisjs/assembler": "8.5.2",
151
+ "@adonisjs/assembler": "8.6.0",
152
152
  "@adonisjs/core": "7.6.0",
153
153
  "@adonisjs/drive": "4.0.0",
154
154
  "@adonisjs/lucid": "22.4.2",
155
- "@aws-sdk/client-s3": "3.1151.0",
155
+ "@aws-sdk/client-s3": "3.1152.0",
156
156
  "@smithy/util-stream": "4.8.2",
157
- "@tanstack/intent": "0.5.5",
157
+ "@tanstack/intent": "0.5.6",
158
158
  "@types/better-sqlite3": "9.6.0",
159
159
  "@types/node": "26.6.5",
160
160
  "aws-sdk-client-mock": "4.1.0",
161
161
  "better-sqlite3": "13.0.3",
162
162
  "luxon": "3.7.2",
163
- "mediabunny": "1.55.7",
163
+ "mediabunny": "1.61.6",
164
164
  "sharp": "0.35.5",
165
165
  "tempura": "0.4.1",
166
166
  "typescript": "7.0.2",
167
- "vitest": "5.0.4"
167
+ "vitest": "5.0.5"
168
168
  },
169
169
  "engines": {
170
170
  "node": ">=24"
@@ -125,7 +125,7 @@ give me a URL", importable unconditionally with feature detection:
125
125
  import { isSingleFileStoreAvailable, removeSingleFile, storeSingleFile } from '@adonis-agora/media/single-file'
126
126
 
127
127
  if (await isSingleFileStoreAvailable()) {
128
- const { url, thumbUrl } = await storeSingleFile({
128
+ const { url, thumbUrl, id, placeholder } = await storeSingleFile({
129
129
  ownerType: 'User',
130
130
  ownerId: String(user.id),
131
131
  collection: 'avatar',
@@ -134,6 +134,7 @@ if (await isSingleFileStoreAvailable()) {
134
134
  contents: upload.bytes, // a Buffer
135
135
  })
136
136
  // thumbUrl is null — not an error — when the 'thumb' conversion isn't configured
137
+ // placeholder is `{ dataUrl, width, height, color }` or null when no placeholder transformer ran
137
138
  }
138
139
 
139
140
  // tests or multi-manager apps pass the manager explicitly:
@@ -5,7 +5,7 @@ description: >-
5
5
  attachExisting / for(ownerType, ownerId), the MediaCollectionConfig policy layer
6
6
  (acceptsMimeTypes exact-match whitelist plus magic-byte signature verification,
7
7
  single:true atomic replace, append-only ordering, per-collection disk), eager vs lazy
8
- ConversionPresets (width/height/fit/format/quality, webp default), ensureConversion,
8
+ ConversionPresets (width/height/fit/format/quality/blur, webp default), ensureConversion,
9
9
  url/signedUrl resolution, delete semantics, deterministic id retries, customProperties,
10
10
  and the MediaRecord.conversions map shared with transformers. Use when uploading files
11
11
  to entities, defining collections, generating thumbnails, or fixing
@@ -102,7 +102,8 @@ Source: `docs/collections-and-conversions.mdx`.
102
102
 
103
103
  ### Pattern 2 — eager vs lazy conversions
104
104
 
105
- `ConversionPreset` maps straight onto sharp. `eager: true` generates synchronously on
105
+ `ConversionPreset` maps straight onto sharp (`blur` is gaussian blur sigma applied after the
106
+ resize; images are auto-oriented from EXIF before resizing). `eager: true` generates synchronously on
106
107
  `attach`; the default is lazy — generated on the **first** `url(id, name)` and then cached on
107
108
  the record, so every later call is a pure lookup.
108
109
 
@@ -292,8 +293,10 @@ defineConfig({
292
293
  ```
293
294
 
294
295
  Mechanism: presets decode the original as an image through sharp; requesting one on a video
295
- or PDF fails inside sharp. Transformers are the seam for everything beyond images and
296
- persist into the same `record.conversions` namespace (name collisions throw
296
+ or PDF fails inside sharp. Transformers are the seam for everything beyond resized image files
297
+ (video packages, metadata probes, image placeholders — `transformers.placeholder()` is
298
+ metadata-only and skips non-`image/*` and SVG records) and persist into the same
299
+ `record.conversions` namespace (name collisions throw
297
300
  `TransformerConflictError` at boot).
298
301
  Source: `docs/collections-and-conversions.mdx` (warn callout), `docs/transformers.mdx`.
299
302