@nhtio/adk 1.20260609.0 → 1.20260610.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.
Files changed (134) hide show
  1. package/CHANGELOG.md +132 -9
  2. package/batteries/llm/ollama/helpers.cjs +9 -0
  3. package/batteries/llm/ollama/helpers.cjs.map +1 -1
  4. package/batteries/llm/ollama/helpers.mjs +9 -0
  5. package/batteries/llm/ollama/helpers.mjs.map +1 -1
  6. package/batteries/llm/openai_chat_completions/helpers.cjs +19 -0
  7. package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -1
  8. package/batteries/llm/openai_chat_completions/helpers.mjs +19 -0
  9. package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -1
  10. package/batteries/media/builder.d.ts +245 -0
  11. package/batteries/media/contracts.cjs +119 -0
  12. package/batteries/media/contracts.cjs.map +1 -0
  13. package/batteries/media/contracts.d.ts +321 -0
  14. package/batteries/media/contracts.mjs +110 -0
  15. package/batteries/media/contracts.mjs.map +1 -0
  16. package/batteries/media/engines/audio_decode.cjs +92 -0
  17. package/batteries/media/engines/audio_decode.cjs.map +1 -0
  18. package/batteries/media/engines/audio_decode.d.ts +46 -0
  19. package/batteries/media/engines/audio_decode.mjs +90 -0
  20. package/batteries/media/engines/audio_decode.mjs.map +1 -0
  21. package/batteries/media/engines/execa_executor.cjs +64 -0
  22. package/batteries/media/engines/execa_executor.cjs.map +1 -0
  23. package/batteries/media/engines/execa_executor.d.ts +54 -0
  24. package/batteries/media/engines/execa_executor.mjs +62 -0
  25. package/batteries/media/engines/execa_executor.mjs.map +1 -0
  26. package/batteries/media/engines/fs_workspace.cjs +84 -0
  27. package/batteries/media/engines/fs_workspace.cjs.map +1 -0
  28. package/batteries/media/engines/fs_workspace.d.ts +51 -0
  29. package/batteries/media/engines/fs_workspace.mjs +82 -0
  30. package/batteries/media/engines/fs_workspace.mjs.map +1 -0
  31. package/batteries/media/engines/jimp.cjs +116 -0
  32. package/batteries/media/engines/jimp.cjs.map +1 -0
  33. package/batteries/media/engines/jimp.d.ts +32 -0
  34. package/batteries/media/engines/jimp.mjs +114 -0
  35. package/batteries/media/engines/jimp.mjs.map +1 -0
  36. package/batteries/media/engines/sharp.cjs +120 -0
  37. package/batteries/media/engines/sharp.cjs.map +1 -0
  38. package/batteries/media/engines/sharp.d.ts +42 -0
  39. package/batteries/media/engines/sharp.mjs +117 -0
  40. package/batteries/media/engines/sharp.mjs.map +1 -0
  41. package/batteries/media/engines/soffice.cjs +246 -0
  42. package/batteries/media/engines/soffice.cjs.map +1 -0
  43. package/batteries/media/engines/soffice.d.ts +39 -0
  44. package/batteries/media/engines/soffice.mjs +244 -0
  45. package/batteries/media/engines/soffice.mjs.map +1 -0
  46. package/batteries/media/engines/tesseract_js.cjs +87 -0
  47. package/batteries/media/engines/tesseract_js.cjs.map +1 -0
  48. package/batteries/media/engines/tesseract_js.d.ts +41 -0
  49. package/batteries/media/engines/tesseract_js.mjs +85 -0
  50. package/batteries/media/engines/tesseract_js.mjs.map +1 -0
  51. package/batteries/media/engines/transformers_asr.cjs +111 -0
  52. package/batteries/media/engines/transformers_asr.cjs.map +1 -0
  53. package/batteries/media/engines/transformers_asr.d.ts +41 -0
  54. package/batteries/media/engines/transformers_asr.mjs +109 -0
  55. package/batteries/media/engines/transformers_asr.mjs.map +1 -0
  56. package/batteries/media/exceptions.d.ts +103 -0
  57. package/batteries/media/forge.cjs +403 -0
  58. package/batteries/media/forge.cjs.map +1 -0
  59. package/batteries/media/forge.d.ts +90 -0
  60. package/batteries/media/forge.mjs +399 -0
  61. package/batteries/media/forge.mjs.map +1 -0
  62. package/batteries/media/formats.d.ts +72 -0
  63. package/batteries/media/index.d.ts +136 -0
  64. package/batteries/media/lint.cjs +339 -0
  65. package/batteries/media/lint.cjs.map +1 -0
  66. package/batteries/media/lint.d.ts +117 -0
  67. package/batteries/media/lint.mjs +331 -0
  68. package/batteries/media/lint.mjs.map +1 -0
  69. package/batteries/media/pipe.d.ts +66 -0
  70. package/batteries/media/plan.d.ts +133 -0
  71. package/batteries/media/registry.d.ts +92 -0
  72. package/batteries/media/runtime.d.ts +105 -0
  73. package/batteries/media/steps/doc.d.ts +33 -0
  74. package/batteries/media/steps/image_audio.d.ts +24 -0
  75. package/batteries/media/steps/ingest.d.ts +25 -0
  76. package/batteries/media/steps/pages.d.ts +18 -0
  77. package/batteries/media/steps/sheet.d.ts +36 -0
  78. package/batteries/media/steps/slides.d.ts +35 -0
  79. package/batteries/media/steps/text.d.ts +43 -0
  80. package/batteries/media/validate.d.ts +49 -0
  81. package/batteries/media/verbs.d.ts +126 -0
  82. package/batteries/media.cjs +3049 -0
  83. package/batteries/media.cjs.map +1 -0
  84. package/batteries/media.mjs +3009 -0
  85. package/batteries/media.mjs.map +1 -0
  86. package/batteries/tools/_shared/index.d.ts +142 -0
  87. package/batteries/tools/_shared.cjs +173 -0
  88. package/batteries/tools/_shared.cjs.map +1 -0
  89. package/batteries/tools/_shared.mjs +164 -0
  90. package/batteries/tools/_shared.mjs.map +1 -0
  91. package/batteries/tools/index.d.ts +2 -0
  92. package/batteries/tools/scrapper/exceptions.d.ts +21 -0
  93. package/batteries/tools/scrapper/index.d.ts +172 -0
  94. package/batteries/tools/scrapper/shared.d.ts +146 -0
  95. package/batteries/tools/scrapper.cjs +8 -0
  96. package/batteries/tools/scrapper.mjs +2 -0
  97. package/batteries/tools/searxng/index.d.ts +54 -20
  98. package/batteries/tools/searxng.cjs +2 -1
  99. package/batteries/tools/searxng.mjs +2 -2
  100. package/batteries/tools/web_retrieval/index.d.ts +186 -0
  101. package/batteries/tools/web_retrieval.cjs +206 -0
  102. package/batteries/tools/web_retrieval.cjs.map +1 -0
  103. package/batteries/tools/web_retrieval.mjs +201 -0
  104. package/batteries/tools/web_retrieval.mjs.map +1 -0
  105. package/batteries/tools.cjs +13 -1
  106. package/batteries/tools.mjs +4 -2
  107. package/batteries.cjs +13 -1
  108. package/batteries.mjs +4 -2
  109. package/common.d.ts +1 -1
  110. package/eslint.cjs +1 -1
  111. package/eslint.mjs +1 -1
  112. package/exceptions-C7FSHEnV.mjs +87 -0
  113. package/exceptions-C7FSHEnV.mjs.map +1 -0
  114. package/exceptions-CQi_lNs1.js +152 -0
  115. package/exceptions-CQi_lNs1.js.map +1 -0
  116. package/index.cjs +2 -2
  117. package/index.mjs +2 -2
  118. package/mcp/adk-docs-corpus.json +1 -1
  119. package/package.json +301 -178
  120. package/scrapper-BOLWYGbD.js +463 -0
  121. package/scrapper-BOLWYGbD.js.map +1 -0
  122. package/scrapper-hDKlNuCT.mjs +433 -0
  123. package/scrapper-hDKlNuCT.mjs.map +1 -0
  124. package/{searxng-Bkrwhwhw.js → searxng-CJtEpa8p.js} +82 -85
  125. package/searxng-CJtEpa8p.js.map +1 -0
  126. package/{searxng-CyA-nEu5.mjs → searxng-riarj_0u.mjs} +76 -85
  127. package/searxng-riarj_0u.mjs.map +1 -0
  128. package/skills/adk-assembly/SKILL.md +2 -2
  129. package/validate-BFaUYHDN.js +1298 -0
  130. package/validate-BFaUYHDN.js.map +1 -0
  131. package/validate-DSZ3wicB.mjs +1215 -0
  132. package/validate-DSZ3wicB.mjs.map +1 -0
  133. package/searxng-Bkrwhwhw.js.map +0 -1
  134. package/searxng-CyA-nEu5.mjs.map +0 -1
@@ -0,0 +1,116 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../../chunk-Ble4zEEl.js");
3
+ const require_tool_registry = require("../../../tool_registry-CKJPze3j.js");
4
+ require("../../../guards.cjs");
5
+ const require_exceptions = require("../../../exceptions-CQi_lNs1.js");
6
+ //#region src/batteries/media/engines/jimp.ts
7
+ /**
8
+ * A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
9
+ * backed by Jimp (pure JavaScript — no native bindings, no binaries).
10
+ *
11
+ * @module @nhtio/adk/batteries/media/engines/jimp
12
+ *
13
+ * @remarks
14
+ * The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate
15
+ * capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,
16
+ * flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —
17
+ * `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,
18
+ * compose a sharp-backed engine instead — the capability declaration is the seam.
19
+ *
20
+ * `jimp` is an optional peer dependency, lazily imported on first actual use (constructing
21
+ * the engine — and therefore the pipeline — never loads it).
22
+ */
23
+ var SUPPORTED_OUTPUT = [
24
+ "png",
25
+ "jpg",
26
+ "jpeg",
27
+ "bmp",
28
+ "gif",
29
+ "tiff"
30
+ ];
31
+ var MIME_BY_FORMAT = {
32
+ png: "image/png",
33
+ jpg: "image/jpeg",
34
+ jpeg: "image/jpeg",
35
+ bmp: "image/bmp",
36
+ gif: "image/gif",
37
+ tiff: "image/tiff"
38
+ };
39
+ /**
40
+ * Construct the Jimp-backed image engine.
41
+ *
42
+ * @param options - Optional module resolver override.
43
+ * @returns The engine.
44
+ */
45
+ var jimpEngine = (options = {}) => {
46
+ let modPromise;
47
+ const getJimp = () => {
48
+ modPromise ??= Promise.resolve(options.jimp ? options.jimp() : import("jimp")).catch((err) => {
49
+ throw new require_exceptions.E_INVALID_MEDIA_PIPELINE_CONFIG([`the jimp engine could not load its peer dependency "jimp": ${require_tool_registry.isError(err) ? err.message : String(err)} — install it (pnpm add jimp)`]);
50
+ });
51
+ return modPromise;
52
+ };
53
+ const mutate = async (request) => {
54
+ const { Jimp } = await getJimp();
55
+ const image = await Jimp.read(request.bytes.buffer.slice(request.bytes.byteOffset, request.bytes.byteOffset + request.bytes.byteLength));
56
+ if (request.resize) {
57
+ const { width, height, fit } = request.resize;
58
+ if (width !== void 0 && height !== void 0) if (fit === "cover") image.cover({
59
+ w: width,
60
+ h: height
61
+ });
62
+ else if (fit === "contain") image.contain({
63
+ w: width,
64
+ h: height
65
+ });
66
+ else image.resize({
67
+ w: width,
68
+ h: height
69
+ });
70
+ else if (width !== void 0) image.resize({ w: width });
71
+ else if (height !== void 0) image.resize({ h: height });
72
+ }
73
+ if (request.rotate) image.rotate(request.rotate);
74
+ if (request.flip) image.flip({
75
+ horizontal: request.flip.horizontal === true,
76
+ vertical: request.flip.vertical === true
77
+ });
78
+ const targetFormat = request.format?.to ?? mimeToFormat(request.mimeType);
79
+ const mimeType = MIME_BY_FORMAT[targetFormat];
80
+ if (!mimeType) throw new Error(`jimp cannot encode "${targetFormat}"; supported: ${SUPPORTED_OUTPUT.join(", ")} (compose a sharp engine for webp/avif)`);
81
+ const quality = request.format?.quality;
82
+ const buffer = mimeType === "image/jpeg" && quality !== void 0 ? await image.getBuffer("image/jpeg", { quality }) : await image.getBuffer(mimeType);
83
+ return {
84
+ bytes: new Uint8Array(buffer),
85
+ mimeType
86
+ };
87
+ };
88
+ return {
89
+ id: "jimp",
90
+ mutates: [{
91
+ over: [
92
+ "image/png",
93
+ "image/jpeg",
94
+ "image/bmp",
95
+ "image/gif",
96
+ "image/tiff"
97
+ ],
98
+ ops: [
99
+ "resize",
100
+ "rotate",
101
+ "flip",
102
+ "strip_metadata"
103
+ ],
104
+ encodes: SUPPORTED_OUTPUT,
105
+ mutate
106
+ }]
107
+ };
108
+ };
109
+ var mimeToFormat = (mimeType) => {
110
+ const sub = mimeType.toLowerCase().split(";")[0].trim().split("/")[1] ?? "png";
111
+ return sub === "jpeg" ? "jpg" : sub;
112
+ };
113
+ //#endregion
114
+ exports.jimpEngine = jimpEngine;
115
+
116
+ //# sourceMappingURL=jimp.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jimp.cjs","names":[],"sources":["../../../../src/batteries/media/engines/jimp.ts"],"sourcesContent":["/**\n * A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}\n * backed by Jimp (pure JavaScript — no native bindings, no binaries).\n *\n * @module @nhtio/adk/batteries/media/engines/jimp\n *\n * @remarks\n * The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate\n * capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,\n * flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —\n * `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,\n * compose a sharp-backed engine instead — the capability declaration is the seam.\n *\n * `jimp` is an optional peer dependency, lazily imported on first actual use (constructing\n * the engine — and therefore the pipeline — never loads it).\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from '../exceptions'\nimport type * as JimpNS from 'jimp'\nimport type { MediaEngine, MutateRequest, EngineBytesResult } from '../contracts'\n\ntype JimpModule = typeof JimpNS\n\n/** Options for {@link jimpEngine}. */\nexport interface JimpEngineOptions {\n /** Override the module resolution (tests / custom builds). Default: `import('jimp')`. */\n jimp?: () => JimpModule | Promise<JimpModule>\n}\n\nconst SUPPORTED_OUTPUT = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'tiff'] as const\n\nconst MIME_BY_FORMAT: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n bmp: 'image/bmp',\n gif: 'image/gif',\n tiff: 'image/tiff',\n}\n\n/**\n * Construct the Jimp-backed image engine.\n *\n * @param options - Optional module resolver override.\n * @returns The engine.\n */\nexport const jimpEngine = (options: JimpEngineOptions = {}): MediaEngine => {\n let modPromise: Promise<JimpModule> | undefined\n const getJimp = (): Promise<JimpModule> => {\n modPromise ??= Promise.resolve(options.jimp ? options.jimp() : import('jimp')).catch((err) => {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `the jimp engine could not load its peer dependency \"jimp\": ${detail} — install it (pnpm add jimp)`,\n ])\n })\n return modPromise\n }\n\n const mutate = async (request: MutateRequest): Promise<EngineBytesResult> => {\n const { Jimp } = await getJimp()\n const image = await Jimp.read(\n request.bytes.buffer.slice(\n request.bytes.byteOffset,\n request.bytes.byteOffset + request.bytes.byteLength\n ) as ArrayBuffer\n )\n\n if (request.resize) {\n const { width, height, fit } = request.resize\n if (width !== undefined && height !== undefined) {\n if (fit === 'cover') image.cover({ w: width, h: height })\n else if (fit === 'contain') image.contain({ w: width, h: height })\n else image.resize({ w: width, h: height })\n } else if (width !== undefined) {\n image.resize({ w: width })\n } else if (height !== undefined) {\n image.resize({ h: height })\n }\n }\n if (request.rotate) {\n image.rotate(request.rotate)\n }\n if (request.flip) {\n image.flip({\n horizontal: request.flip.horizontal === true,\n vertical: request.flip.vertical === true,\n })\n }\n\n const targetFormat = request.format?.to ?? mimeToFormat(request.mimeType)\n const mimeType = MIME_BY_FORMAT[targetFormat]\n if (!mimeType) {\n throw new Error(\n `jimp cannot encode \"${targetFormat}\"; supported: ${SUPPORTED_OUTPUT.join(', ')} (compose a sharp engine for webp/avif)`\n )\n }\n const quality = request.format?.quality\n const buffer =\n mimeType === 'image/jpeg' && quality !== undefined\n ? await image.getBuffer('image/jpeg', { quality })\n : await image.getBuffer(mimeType as 'image/png')\n return { bytes: new Uint8Array(buffer), mimeType }\n }\n\n return {\n id: 'jimp',\n mutates: [\n {\n over: ['image/png', 'image/jpeg', 'image/bmp', 'image/gif', 'image/tiff'],\n ops: ['resize', 'rotate', 'flip', 'strip_metadata'],\n encodes: SUPPORTED_OUTPUT,\n mutate,\n },\n ],\n }\n}\n\nconst mimeToFormat = (mimeType: string): string => {\n const sub = mimeType.toLowerCase().split(';')[0].trim().split('/')[1] ?? 'png'\n return sub === 'jpeg' ? 'jpg' : sub\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA8BA,IAAM,mBAAmB;CAAC;CAAO;CAAO;CAAQ;CAAO;CAAO;AAAM;AAEpE,IAAM,iBAAyC;CAC7C,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,KAAK;CACL,MAAM;AACR;;;;;;;AAQA,IAAa,cAAc,UAA6B,CAAC,MAAmB;CAC1E,IAAI;CACJ,MAAM,gBAAqC;EACzC,eAAe,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,KAAK,IAAI,OAAO,OAAO,EAAE,OAAO,QAAQ;GAE5F,MAAM,IAAI,mBAAA,gCAAgC,CACxC,8DAFa,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAEiB,8BACvE,CAAC;EACH,CAAC;EACD,OAAO;CACT;CAEA,MAAM,SAAS,OAAO,YAAuD;EAC3E,MAAM,EAAE,SAAS,MAAM,QAAQ;EAC/B,MAAM,QAAQ,MAAM,KAAK,KACvB,QAAQ,MAAM,OAAO,MACnB,QAAQ,MAAM,YACd,QAAQ,MAAM,aAAa,QAAQ,MAAM,UAC3C,CACF;EAEA,IAAI,QAAQ,QAAQ;GAClB,MAAM,EAAE,OAAO,QAAQ,QAAQ,QAAQ;GACvC,IAAI,UAAU,KAAA,KAAa,WAAW,KAAA,GACpC,IAAI,QAAQ,SAAS,MAAM,MAAM;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QACnD,IAAI,QAAQ,WAAW,MAAM,QAAQ;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QAC5D,MAAM,OAAO;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QACpC,IAAI,UAAU,KAAA,GACnB,MAAM,OAAO,EAAE,GAAG,MAAM,CAAC;QACpB,IAAI,WAAW,KAAA,GACpB,MAAM,OAAO,EAAE,GAAG,OAAO,CAAC;EAE9B;EACA,IAAI,QAAQ,QACV,MAAM,OAAO,QAAQ,MAAM;EAE7B,IAAI,QAAQ,MACV,MAAM,KAAK;GACT,YAAY,QAAQ,KAAK,eAAe;GACxC,UAAU,QAAQ,KAAK,aAAa;EACtC,CAAC;EAGH,MAAM,eAAe,QAAQ,QAAQ,MAAM,aAAa,QAAQ,QAAQ;EACxE,MAAM,WAAW,eAAe;EAChC,IAAI,CAAC,UACH,MAAM,IAAI,MACR,uBAAuB,aAAa,gBAAgB,iBAAiB,KAAK,IAAI,EAAE,wCAClF;EAEF,MAAM,UAAU,QAAQ,QAAQ;EAChC,MAAM,SACJ,aAAa,gBAAgB,YAAY,KAAA,IACrC,MAAM,MAAM,UAAU,cAAc,EAAE,QAAQ,CAAC,IAC/C,MAAM,MAAM,UAAU,QAAuB;EACnD,OAAO;GAAE,OAAO,IAAI,WAAW,MAAM;GAAG;EAAS;CACnD;CAEA,OAAO;EACL,IAAI;EACJ,SAAS,CACP;GACE,MAAM;IAAC;IAAa;IAAc;IAAa;IAAa;GAAY;GACxE,KAAK;IAAC;IAAU;IAAU;IAAQ;GAAgB;GAClD,SAAS;GACT;EACF,CACF;CACF;AACF;AAEA,IAAM,gBAAgB,aAA6B;CACjD,MAAM,MAAM,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM;CACzE,OAAO,QAAQ,SAAS,QAAQ;AAClC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
3
+ * backed by Jimp (pure JavaScript — no native bindings, no binaries).
4
+ *
5
+ * @module @nhtio/adk/batteries/media/engines/jimp
6
+ *
7
+ * @remarks
8
+ * The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate
9
+ * capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,
10
+ * flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —
11
+ * `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,
12
+ * compose a sharp-backed engine instead — the capability declaration is the seam.
13
+ *
14
+ * `jimp` is an optional peer dependency, lazily imported on first actual use (constructing
15
+ * the engine — and therefore the pipeline — never loads it).
16
+ */
17
+ import type * as JimpNS from 'jimp';
18
+ import type { MediaEngine } from "../contracts";
19
+ type JimpModule = typeof JimpNS;
20
+ /** Options for {@link jimpEngine}. */
21
+ export interface JimpEngineOptions {
22
+ /** Override the module resolution (tests / custom builds). Default: `import('jimp')`. */
23
+ jimp?: () => JimpModule | Promise<JimpModule>;
24
+ }
25
+ /**
26
+ * Construct the Jimp-backed image engine.
27
+ *
28
+ * @param options - Optional module resolver override.
29
+ * @returns The engine.
30
+ */
31
+ export declare const jimpEngine: (options?: JimpEngineOptions) => MediaEngine;
32
+ export {};
@@ -0,0 +1,114 @@
1
+ import { o as isError } from "../../../tool_registry-791Vrjtf.mjs";
2
+ import "../../../guards.mjs";
3
+ import { t as E_INVALID_MEDIA_PIPELINE_CONFIG } from "../../../exceptions-C7FSHEnV.mjs";
4
+ //#region src/batteries/media/engines/jimp.ts
5
+ /**
6
+ * A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
7
+ * backed by Jimp (pure JavaScript — no native bindings, no binaries).
8
+ *
9
+ * @module @nhtio/adk/batteries/media/engines/jimp
10
+ *
11
+ * @remarks
12
+ * The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate
13
+ * capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,
14
+ * flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —
15
+ * `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,
16
+ * compose a sharp-backed engine instead — the capability declaration is the seam.
17
+ *
18
+ * `jimp` is an optional peer dependency, lazily imported on first actual use (constructing
19
+ * the engine — and therefore the pipeline — never loads it).
20
+ */
21
+ var SUPPORTED_OUTPUT = [
22
+ "png",
23
+ "jpg",
24
+ "jpeg",
25
+ "bmp",
26
+ "gif",
27
+ "tiff"
28
+ ];
29
+ var MIME_BY_FORMAT = {
30
+ png: "image/png",
31
+ jpg: "image/jpeg",
32
+ jpeg: "image/jpeg",
33
+ bmp: "image/bmp",
34
+ gif: "image/gif",
35
+ tiff: "image/tiff"
36
+ };
37
+ /**
38
+ * Construct the Jimp-backed image engine.
39
+ *
40
+ * @param options - Optional module resolver override.
41
+ * @returns The engine.
42
+ */
43
+ var jimpEngine = (options = {}) => {
44
+ let modPromise;
45
+ const getJimp = () => {
46
+ modPromise ??= Promise.resolve(options.jimp ? options.jimp() : import("jimp")).catch((err) => {
47
+ throw new E_INVALID_MEDIA_PIPELINE_CONFIG([`the jimp engine could not load its peer dependency "jimp": ${isError(err) ? err.message : String(err)} — install it (pnpm add jimp)`]);
48
+ });
49
+ return modPromise;
50
+ };
51
+ const mutate = async (request) => {
52
+ const { Jimp } = await getJimp();
53
+ const image = await Jimp.read(request.bytes.buffer.slice(request.bytes.byteOffset, request.bytes.byteOffset + request.bytes.byteLength));
54
+ if (request.resize) {
55
+ const { width, height, fit } = request.resize;
56
+ if (width !== void 0 && height !== void 0) if (fit === "cover") image.cover({
57
+ w: width,
58
+ h: height
59
+ });
60
+ else if (fit === "contain") image.contain({
61
+ w: width,
62
+ h: height
63
+ });
64
+ else image.resize({
65
+ w: width,
66
+ h: height
67
+ });
68
+ else if (width !== void 0) image.resize({ w: width });
69
+ else if (height !== void 0) image.resize({ h: height });
70
+ }
71
+ if (request.rotate) image.rotate(request.rotate);
72
+ if (request.flip) image.flip({
73
+ horizontal: request.flip.horizontal === true,
74
+ vertical: request.flip.vertical === true
75
+ });
76
+ const targetFormat = request.format?.to ?? mimeToFormat(request.mimeType);
77
+ const mimeType = MIME_BY_FORMAT[targetFormat];
78
+ if (!mimeType) throw new Error(`jimp cannot encode "${targetFormat}"; supported: ${SUPPORTED_OUTPUT.join(", ")} (compose a sharp engine for webp/avif)`);
79
+ const quality = request.format?.quality;
80
+ const buffer = mimeType === "image/jpeg" && quality !== void 0 ? await image.getBuffer("image/jpeg", { quality }) : await image.getBuffer(mimeType);
81
+ return {
82
+ bytes: new Uint8Array(buffer),
83
+ mimeType
84
+ };
85
+ };
86
+ return {
87
+ id: "jimp",
88
+ mutates: [{
89
+ over: [
90
+ "image/png",
91
+ "image/jpeg",
92
+ "image/bmp",
93
+ "image/gif",
94
+ "image/tiff"
95
+ ],
96
+ ops: [
97
+ "resize",
98
+ "rotate",
99
+ "flip",
100
+ "strip_metadata"
101
+ ],
102
+ encodes: SUPPORTED_OUTPUT,
103
+ mutate
104
+ }]
105
+ };
106
+ };
107
+ var mimeToFormat = (mimeType) => {
108
+ const sub = mimeType.toLowerCase().split(";")[0].trim().split("/")[1] ?? "png";
109
+ return sub === "jpeg" ? "jpg" : sub;
110
+ };
111
+ //#endregion
112
+ export { jimpEngine };
113
+
114
+ //# sourceMappingURL=jimp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jimp.mjs","names":[],"sources":["../../../../src/batteries/media/engines/jimp.ts"],"sourcesContent":["/**\n * A cross-environment image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}\n * backed by Jimp (pure JavaScript — no native bindings, no binaries).\n *\n * @module @nhtio/adk/batteries/media/engines/jimp\n *\n * @remarks\n * The local-by-default raster engine: runs anywhere TypeScript runs. Declares one mutate\n * capability over png/jpeg/bmp/gif/tiff with resize (cover/contain approximations), rotate,\n * flip, quality, and metadata stripping (Jimp re-encodes pixels, so EXIF never survives —\n * `strip_metadata` is inherently satisfied). For webp/avif output or native-speed processing,\n * compose a sharp-backed engine instead — the capability declaration is the seam.\n *\n * `jimp` is an optional peer dependency, lazily imported on first actual use (constructing\n * the engine — and therefore the pipeline — never loads it).\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from '../exceptions'\nimport type * as JimpNS from 'jimp'\nimport type { MediaEngine, MutateRequest, EngineBytesResult } from '../contracts'\n\ntype JimpModule = typeof JimpNS\n\n/** Options for {@link jimpEngine}. */\nexport interface JimpEngineOptions {\n /** Override the module resolution (tests / custom builds). Default: `import('jimp')`. */\n jimp?: () => JimpModule | Promise<JimpModule>\n}\n\nconst SUPPORTED_OUTPUT = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'tiff'] as const\n\nconst MIME_BY_FORMAT: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n bmp: 'image/bmp',\n gif: 'image/gif',\n tiff: 'image/tiff',\n}\n\n/**\n * Construct the Jimp-backed image engine.\n *\n * @param options - Optional module resolver override.\n * @returns The engine.\n */\nexport const jimpEngine = (options: JimpEngineOptions = {}): MediaEngine => {\n let modPromise: Promise<JimpModule> | undefined\n const getJimp = (): Promise<JimpModule> => {\n modPromise ??= Promise.resolve(options.jimp ? options.jimp() : import('jimp')).catch((err) => {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `the jimp engine could not load its peer dependency \"jimp\": ${detail} — install it (pnpm add jimp)`,\n ])\n })\n return modPromise\n }\n\n const mutate = async (request: MutateRequest): Promise<EngineBytesResult> => {\n const { Jimp } = await getJimp()\n const image = await Jimp.read(\n request.bytes.buffer.slice(\n request.bytes.byteOffset,\n request.bytes.byteOffset + request.bytes.byteLength\n ) as ArrayBuffer\n )\n\n if (request.resize) {\n const { width, height, fit } = request.resize\n if (width !== undefined && height !== undefined) {\n if (fit === 'cover') image.cover({ w: width, h: height })\n else if (fit === 'contain') image.contain({ w: width, h: height })\n else image.resize({ w: width, h: height })\n } else if (width !== undefined) {\n image.resize({ w: width })\n } else if (height !== undefined) {\n image.resize({ h: height })\n }\n }\n if (request.rotate) {\n image.rotate(request.rotate)\n }\n if (request.flip) {\n image.flip({\n horizontal: request.flip.horizontal === true,\n vertical: request.flip.vertical === true,\n })\n }\n\n const targetFormat = request.format?.to ?? mimeToFormat(request.mimeType)\n const mimeType = MIME_BY_FORMAT[targetFormat]\n if (!mimeType) {\n throw new Error(\n `jimp cannot encode \"${targetFormat}\"; supported: ${SUPPORTED_OUTPUT.join(', ')} (compose a sharp engine for webp/avif)`\n )\n }\n const quality = request.format?.quality\n const buffer =\n mimeType === 'image/jpeg' && quality !== undefined\n ? await image.getBuffer('image/jpeg', { quality })\n : await image.getBuffer(mimeType as 'image/png')\n return { bytes: new Uint8Array(buffer), mimeType }\n }\n\n return {\n id: 'jimp',\n mutates: [\n {\n over: ['image/png', 'image/jpeg', 'image/bmp', 'image/gif', 'image/tiff'],\n ops: ['resize', 'rotate', 'flip', 'strip_metadata'],\n encodes: SUPPORTED_OUTPUT,\n mutate,\n },\n ],\n }\n}\n\nconst mimeToFormat = (mimeType: string): string => {\n const sub = mimeType.toLowerCase().split(';')[0].trim().split('/')[1] ?? 'png'\n return sub === 'jpeg' ? 'jpg' : sub\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA8BA,IAAM,mBAAmB;CAAC;CAAO;CAAO;CAAQ;CAAO;CAAO;AAAM;AAEpE,IAAM,iBAAyC;CAC7C,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,KAAK;CACL,MAAM;AACR;;;;;;;AAQA,IAAa,cAAc,UAA6B,CAAC,MAAmB;CAC1E,IAAI;CACJ,MAAM,gBAAqC;EACzC,eAAe,QAAQ,QAAQ,QAAQ,OAAO,QAAQ,KAAK,IAAI,OAAO,OAAO,EAAE,OAAO,QAAQ;GAE5F,MAAM,IAAI,gCAAgC,CACxC,8DAFa,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAEiB,8BACvE,CAAC;EACH,CAAC;EACD,OAAO;CACT;CAEA,MAAM,SAAS,OAAO,YAAuD;EAC3E,MAAM,EAAE,SAAS,MAAM,QAAQ;EAC/B,MAAM,QAAQ,MAAM,KAAK,KACvB,QAAQ,MAAM,OAAO,MACnB,QAAQ,MAAM,YACd,QAAQ,MAAM,aAAa,QAAQ,MAAM,UAC3C,CACF;EAEA,IAAI,QAAQ,QAAQ;GAClB,MAAM,EAAE,OAAO,QAAQ,QAAQ,QAAQ;GACvC,IAAI,UAAU,KAAA,KAAa,WAAW,KAAA,GACpC,IAAI,QAAQ,SAAS,MAAM,MAAM;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QACnD,IAAI,QAAQ,WAAW,MAAM,QAAQ;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QAC5D,MAAM,OAAO;IAAE,GAAG;IAAO,GAAG;GAAO,CAAC;QACpC,IAAI,UAAU,KAAA,GACnB,MAAM,OAAO,EAAE,GAAG,MAAM,CAAC;QACpB,IAAI,WAAW,KAAA,GACpB,MAAM,OAAO,EAAE,GAAG,OAAO,CAAC;EAE9B;EACA,IAAI,QAAQ,QACV,MAAM,OAAO,QAAQ,MAAM;EAE7B,IAAI,QAAQ,MACV,MAAM,KAAK;GACT,YAAY,QAAQ,KAAK,eAAe;GACxC,UAAU,QAAQ,KAAK,aAAa;EACtC,CAAC;EAGH,MAAM,eAAe,QAAQ,QAAQ,MAAM,aAAa,QAAQ,QAAQ;EACxE,MAAM,WAAW,eAAe;EAChC,IAAI,CAAC,UACH,MAAM,IAAI,MACR,uBAAuB,aAAa,gBAAgB,iBAAiB,KAAK,IAAI,EAAE,wCAClF;EAEF,MAAM,UAAU,QAAQ,QAAQ;EAChC,MAAM,SACJ,aAAa,gBAAgB,YAAY,KAAA,IACrC,MAAM,MAAM,UAAU,cAAc,EAAE,QAAQ,CAAC,IAC/C,MAAM,MAAM,UAAU,QAAuB;EACnD,OAAO;GAAE,OAAO,IAAI,WAAW,MAAM;GAAG;EAAS;CACnD;CAEA,OAAO;EACL,IAAI;EACJ,SAAS,CACP;GACE,MAAM;IAAC;IAAa;IAAc;IAAa;IAAa;GAAY;GACxE,KAAK;IAAC;IAAU;IAAU;IAAQ;GAAgB;GAClD,SAAS;GACT;EACF,CACF;CACF;AACF;AAEA,IAAM,gBAAgB,aAA6B;CACjD,MAAM,MAAM,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM;CACzE,OAAO,QAAQ,SAAS,QAAQ;AAClC"}
@@ -0,0 +1,120 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ require("../../../chunk-Ble4zEEl.js");
3
+ const require_tool_registry = require("../../../tool_registry-CKJPze3j.js");
4
+ require("../../../guards.cjs");
5
+ const require_exceptions = require("../../../exceptions-CQi_lNs1.js");
6
+ //#region src/batteries/media/engines/sharp.ts
7
+ /**
8
+ * A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
9
+ * backed by sharp (libvips bindings — fast, full-format).
10
+ *
11
+ * @module @nhtio/adk/batteries/media/engines/sharp
12
+ *
13
+ * @remarks
14
+ * The performance/fidelity engine for Node deployments: native speed plus webp/avif output
15
+ * and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a
16
+ * cross-environment engine compose the jimp implementation instead — the capability
17
+ * declaration is the seam, and BYO instances adapt via {@link fromSharp}.
18
+ *
19
+ * `sharp` is an optional peer dependency, lazily imported on first actual use.
20
+ */
21
+ var SUPPORTED_OUTPUT = [
22
+ "png",
23
+ "jpg",
24
+ "jpeg",
25
+ "webp",
26
+ "tiff",
27
+ "avif",
28
+ "gif"
29
+ ];
30
+ var MIME_BY_FORMAT = {
31
+ png: "image/png",
32
+ jpg: "image/jpeg",
33
+ jpeg: "image/jpeg",
34
+ webp: "image/webp",
35
+ tiff: "image/tiff",
36
+ avif: "image/avif",
37
+ gif: "image/gif"
38
+ };
39
+ var resolveSharp = async (supplied) => {
40
+ try {
41
+ const mod = await (supplied ? supplied() : import("sharp"));
42
+ const fn = typeof mod === "function" ? mod : mod.default;
43
+ if (typeof fn !== "function") throw new Error("sharp did not resolve to a function");
44
+ return fn;
45
+ } catch (err) {
46
+ throw new require_exceptions.E_INVALID_MEDIA_PIPELINE_CONFIG([`the sharp engine could not load its peer dependency "sharp": ${require_tool_registry.isError(err) ? err.message : String(err)} — install it (pnpm add sharp); note sharp is Node-only`]);
47
+ }
48
+ };
49
+ /** Run a fused mutate request through a sharp instance function. */
50
+ var runTransform = async (sharp, request) => {
51
+ let img = sharp(request.bytes);
52
+ if (request.rotate) img = img.rotate(request.rotate);
53
+ if (request.flip?.vertical) img = img.flip();
54
+ if (request.flip?.horizontal) img = img.flop();
55
+ if (request.resize && (request.resize.width !== void 0 || request.resize.height !== void 0)) img = img.resize({
56
+ width: request.resize.width,
57
+ height: request.resize.height,
58
+ fit: request.resize.fit ?? "cover"
59
+ });
60
+ const target = request.format?.to ?? mimeToFormat(request.mimeType);
61
+ const mimeType = MIME_BY_FORMAT[target];
62
+ if (!mimeType) throw new Error(`sharp cannot encode "${target}"; supported: ${SUPPORTED_OUTPUT.join(", ")}`);
63
+ const formatKey = target === "jpg" ? "jpeg" : target;
64
+ img = img.toFormat(formatKey, request.format?.quality !== void 0 ? { quality: request.format.quality } : {});
65
+ if (request.stripMetadata !== true) img = img.keepMetadata();
66
+ const buffer = await img.toBuffer();
67
+ return {
68
+ bytes: new Uint8Array(buffer),
69
+ mimeType
70
+ };
71
+ };
72
+ /** Build the single mutate capability over a sharp source. */
73
+ var capabilityOf = (run) => ({
74
+ over: ["image/*"],
75
+ ops: [
76
+ "resize",
77
+ "rotate",
78
+ "flip",
79
+ "strip_metadata"
80
+ ],
81
+ encodes: SUPPORTED_OUTPUT,
82
+ mutate: run
83
+ });
84
+ /**
85
+ * Construct the sharp-backed image engine.
86
+ *
87
+ * @param options - Optional module resolver override.
88
+ * @returns The engine.
89
+ */
90
+ var sharpEngine = (options = {}) => {
91
+ let sharpPromise;
92
+ const getSharp = () => {
93
+ sharpPromise ??= resolveSharp(options.sharp);
94
+ return sharpPromise;
95
+ };
96
+ return {
97
+ id: "sharp",
98
+ mutates: [capabilityOf(async (request) => runTransform(await getSharp(), request))]
99
+ };
100
+ };
101
+ /**
102
+ * Adapt an already-configured sharp module (your import, your build flags) to the engine
103
+ * contract — the BYO transformer.
104
+ *
105
+ * @param sharp - The sharp function you imported.
106
+ * @returns The engine.
107
+ */
108
+ var fromSharp = (sharp) => ({
109
+ id: "sharp",
110
+ mutates: [capabilityOf(async (request) => runTransform(sharp, request))]
111
+ });
112
+ var mimeToFormat = (mimeType) => {
113
+ const sub = mimeType.toLowerCase().split(";")[0].trim().split("/")[1] ?? "png";
114
+ return sub === "jpeg" ? "jpg" : sub;
115
+ };
116
+ //#endregion
117
+ exports.fromSharp = fromSharp;
118
+ exports.sharpEngine = sharpEngine;
119
+
120
+ //# sourceMappingURL=sharp.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharp.cjs","names":[],"sources":["../../../../src/batteries/media/engines/sharp.ts"],"sourcesContent":["/**\n * A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}\n * backed by sharp (libvips bindings — fast, full-format).\n *\n * @module @nhtio/adk/batteries/media/engines/sharp\n *\n * @remarks\n * The performance/fidelity engine for Node deployments: native speed plus webp/avif output\n * and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a\n * cross-environment engine compose the jimp implementation instead — the capability\n * declaration is the seam, and BYO instances adapt via {@link fromSharp}.\n *\n * `sharp` is an optional peer dependency, lazily imported on first actual use.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { default as SharpDefault } from 'sharp'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from '../exceptions'\nimport type { MediaEngine, MutateCapability, MutateRequest, EngineBytesResult } from '../contracts'\n\ntype SharpFn = typeof SharpDefault\n\n/** Options for {@link sharpEngine}. */\nexport interface SharpEngineOptions {\n /** Override the module resolution (electron/custom builds). Default: `import('sharp')`. */\n sharp?: () => SharpFn | { default: SharpFn } | Promise<SharpFn | { default: SharpFn }>\n}\n\nconst SUPPORTED_OUTPUT = ['png', 'jpg', 'jpeg', 'webp', 'tiff', 'avif', 'gif'] as const\n\nconst MIME_BY_FORMAT: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n webp: 'image/webp',\n tiff: 'image/tiff',\n avif: 'image/avif',\n gif: 'image/gif',\n}\n\nconst resolveSharp = async (supplied: SharpEngineOptions['sharp']): Promise<SharpFn> => {\n try {\n const mod = await (supplied ? supplied() : import('sharp'))\n const fn = typeof mod === 'function' ? mod : (mod as { default: SharpFn }).default\n if (typeof fn !== 'function') throw new Error('sharp did not resolve to a function')\n return fn\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `the sharp engine could not load its peer dependency \"sharp\": ${detail} — install it (pnpm add sharp); note sharp is Node-only`,\n ])\n }\n}\n\n/** Run a fused mutate request through a sharp instance function. */\nconst runTransform = async (sharp: SharpFn, request: MutateRequest): Promise<EngineBytesResult> => {\n let img = sharp(request.bytes)\n if (request.rotate) img = img.rotate(request.rotate)\n if (request.flip?.vertical) img = img.flip()\n if (request.flip?.horizontal) img = img.flop()\n if (\n request.resize &&\n (request.resize.width !== undefined || request.resize.height !== undefined)\n ) {\n img = img.resize({\n width: request.resize.width,\n height: request.resize.height,\n fit: request.resize.fit ?? 'cover',\n })\n }\n const target = request.format?.to ?? mimeToFormat(request.mimeType)\n const mimeType = MIME_BY_FORMAT[target]\n if (!mimeType) {\n throw new Error(`sharp cannot encode \"${target}\"; supported: ${SUPPORTED_OUTPUT.join(', ')}`)\n }\n const formatKey = (target === 'jpg' ? 'jpeg' : target) as\n | 'png'\n | 'jpeg'\n | 'webp'\n | 'tiff'\n | 'avif'\n | 'gif'\n img = img.toFormat(\n formatKey,\n request.format?.quality !== undefined ? { quality: request.format.quality } : {}\n )\n if (request.stripMetadata !== true) {\n // sharp strips metadata by default; keep it when NOT asked to strip.\n img = img.keepMetadata()\n }\n const buffer = await img.toBuffer()\n return { bytes: new Uint8Array(buffer), mimeType }\n}\n\n/** Build the single mutate capability over a sharp source. */\nconst capabilityOf = (\n run: (request: MutateRequest) => Promise<EngineBytesResult>\n): MutateCapability => ({\n over: ['image/*'],\n ops: ['resize', 'rotate', 'flip', 'strip_metadata'],\n encodes: SUPPORTED_OUTPUT,\n mutate: run,\n})\n\n/**\n * Construct the sharp-backed image engine.\n *\n * @param options - Optional module resolver override.\n * @returns The engine.\n */\nexport const sharpEngine = (options: SharpEngineOptions = {}): MediaEngine => {\n let sharpPromise: Promise<SharpFn> | undefined\n const getSharp = (): Promise<SharpFn> => {\n sharpPromise ??= resolveSharp(options.sharp)\n return sharpPromise\n }\n return {\n id: 'sharp',\n mutates: [capabilityOf(async (request) => runTransform(await getSharp(), request))],\n }\n}\n\n/**\n * Adapt an already-configured sharp module (your import, your build flags) to the engine\n * contract — the BYO transformer.\n *\n * @param sharp - The sharp function you imported.\n * @returns The engine.\n */\nexport const fromSharp = (sharp: SharpFn): MediaEngine => ({\n id: 'sharp',\n mutates: [capabilityOf(async (request) => runTransform(sharp, request))],\n})\n\nconst mimeToFormat = (mimeType: string): string => {\n const sub = mimeType.toLowerCase().split(';')[0].trim().split('/')[1] ?? 'png'\n return sub === 'jpeg' ? 'jpg' : sub\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA4BA,IAAM,mBAAmB;CAAC;CAAO;CAAO;CAAQ;CAAQ;CAAQ;CAAQ;AAAK;AAE7E,IAAM,iBAAyC;CAC7C,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;AACP;AAEA,IAAM,eAAe,OAAO,aAA4D;CACtF,IAAI;EACF,MAAM,MAAM,OAAO,WAAW,SAAS,IAAI,OAAO;EAClD,MAAM,KAAK,OAAO,QAAQ,aAAa,MAAO,IAA6B;EAC3E,IAAI,OAAO,OAAO,YAAY,MAAM,IAAI,MAAM,qCAAqC;EACnF,OAAO;CACT,SAAS,KAAK;EAEZ,MAAM,IAAI,mBAAA,gCAAgC,CACxC,gEAFa,sBAAA,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAEmB,wDACzE,CAAC;CACH;AACF;;AAGA,IAAM,eAAe,OAAO,OAAgB,YAAuD;CACjG,IAAI,MAAM,MAAM,QAAQ,KAAK;CAC7B,IAAI,QAAQ,QAAQ,MAAM,IAAI,OAAO,QAAQ,MAAM;CACnD,IAAI,QAAQ,MAAM,UAAU,MAAM,IAAI,KAAK;CAC3C,IAAI,QAAQ,MAAM,YAAY,MAAM,IAAI,KAAK;CAC7C,IACE,QAAQ,WACP,QAAQ,OAAO,UAAU,KAAA,KAAa,QAAQ,OAAO,WAAW,KAAA,IAEjE,MAAM,IAAI,OAAO;EACf,OAAO,QAAQ,OAAO;EACtB,QAAQ,QAAQ,OAAO;EACvB,KAAK,QAAQ,OAAO,OAAO;CAC7B,CAAC;CAEH,MAAM,SAAS,QAAQ,QAAQ,MAAM,aAAa,QAAQ,QAAQ;CAClE,MAAM,WAAW,eAAe;CAChC,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,wBAAwB,OAAO,gBAAgB,iBAAiB,KAAK,IAAI,GAAG;CAE9F,MAAM,YAAa,WAAW,QAAQ,SAAS;CAO/C,MAAM,IAAI,SACR,WACA,QAAQ,QAAQ,YAAY,KAAA,IAAY,EAAE,SAAS,QAAQ,OAAO,QAAQ,IAAI,CAAC,CACjF;CACA,IAAI,QAAQ,kBAAkB,MAE5B,MAAM,IAAI,aAAa;CAEzB,MAAM,SAAS,MAAM,IAAI,SAAS;CAClC,OAAO;EAAE,OAAO,IAAI,WAAW,MAAM;EAAG;CAAS;AACnD;;AAGA,IAAM,gBACJ,SACsB;CACtB,MAAM,CAAC,SAAS;CAChB,KAAK;EAAC;EAAU;EAAU;EAAQ;CAAgB;CAClD,SAAS;CACT,QAAQ;AACV;;;;;;;AAQA,IAAa,eAAe,UAA8B,CAAC,MAAmB;CAC5E,IAAI;CACJ,MAAM,iBAAmC;EACvC,iBAAiB,aAAa,QAAQ,KAAK;EAC3C,OAAO;CACT;CACA,OAAO;EACL,IAAI;EACJ,SAAS,CAAC,aAAa,OAAO,YAAY,aAAa,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC;CACpF;AACF;;;;;;;;AASA,IAAa,aAAa,WAAiC;CACzD,IAAI;CACJ,SAAS,CAAC,aAAa,OAAO,YAAY,aAAa,OAAO,OAAO,CAAC,CAAC;AACzE;AAEA,IAAM,gBAAgB,aAA6B;CACjD,MAAM,MAAM,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM;CACzE,OAAO,QAAQ,SAAS,QAAQ;AAClC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
3
+ * backed by sharp (libvips bindings — fast, full-format).
4
+ *
5
+ * @module @nhtio/adk/batteries/media/engines/sharp
6
+ *
7
+ * @remarks
8
+ * The performance/fidelity engine for Node deployments: native speed plus webp/avif output
9
+ * and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a
10
+ * cross-environment engine compose the jimp implementation instead — the capability
11
+ * declaration is the seam, and BYO instances adapt via {@link fromSharp}.
12
+ *
13
+ * `sharp` is an optional peer dependency, lazily imported on first actual use.
14
+ */
15
+ import { default as SharpDefault } from 'sharp';
16
+ import type { MediaEngine } from "../contracts";
17
+ type SharpFn = typeof SharpDefault;
18
+ /** Options for {@link sharpEngine}. */
19
+ export interface SharpEngineOptions {
20
+ /** Override the module resolution (electron/custom builds). Default: `import('sharp')`. */
21
+ sharp?: () => SharpFn | {
22
+ default: SharpFn;
23
+ } | Promise<SharpFn | {
24
+ default: SharpFn;
25
+ }>;
26
+ }
27
+ /**
28
+ * Construct the sharp-backed image engine.
29
+ *
30
+ * @param options - Optional module resolver override.
31
+ * @returns The engine.
32
+ */
33
+ export declare const sharpEngine: (options?: SharpEngineOptions) => MediaEngine;
34
+ /**
35
+ * Adapt an already-configured sharp module (your import, your build flags) to the engine
36
+ * contract — the BYO transformer.
37
+ *
38
+ * @param sharp - The sharp function you imported.
39
+ * @returns The engine.
40
+ */
41
+ export declare const fromSharp: (sharp: SharpFn) => MediaEngine;
42
+ export {};
@@ -0,0 +1,117 @@
1
+ import { o as isError } from "../../../tool_registry-791Vrjtf.mjs";
2
+ import "../../../guards.mjs";
3
+ import { t as E_INVALID_MEDIA_PIPELINE_CONFIG } from "../../../exceptions-C7FSHEnV.mjs";
4
+ //#region src/batteries/media/engines/sharp.ts
5
+ /**
6
+ * A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}
7
+ * backed by sharp (libvips bindings — fast, full-format).
8
+ *
9
+ * @module @nhtio/adk/batteries/media/engines/sharp
10
+ *
11
+ * @remarks
12
+ * The performance/fidelity engine for Node deployments: native speed plus webp/avif output
13
+ * and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a
14
+ * cross-environment engine compose the jimp implementation instead — the capability
15
+ * declaration is the seam, and BYO instances adapt via {@link fromSharp}.
16
+ *
17
+ * `sharp` is an optional peer dependency, lazily imported on first actual use.
18
+ */
19
+ var SUPPORTED_OUTPUT = [
20
+ "png",
21
+ "jpg",
22
+ "jpeg",
23
+ "webp",
24
+ "tiff",
25
+ "avif",
26
+ "gif"
27
+ ];
28
+ var MIME_BY_FORMAT = {
29
+ png: "image/png",
30
+ jpg: "image/jpeg",
31
+ jpeg: "image/jpeg",
32
+ webp: "image/webp",
33
+ tiff: "image/tiff",
34
+ avif: "image/avif",
35
+ gif: "image/gif"
36
+ };
37
+ var resolveSharp = async (supplied) => {
38
+ try {
39
+ const mod = await (supplied ? supplied() : import("sharp"));
40
+ const fn = typeof mod === "function" ? mod : mod.default;
41
+ if (typeof fn !== "function") throw new Error("sharp did not resolve to a function");
42
+ return fn;
43
+ } catch (err) {
44
+ throw new E_INVALID_MEDIA_PIPELINE_CONFIG([`the sharp engine could not load its peer dependency "sharp": ${isError(err) ? err.message : String(err)} — install it (pnpm add sharp); note sharp is Node-only`]);
45
+ }
46
+ };
47
+ /** Run a fused mutate request through a sharp instance function. */
48
+ var runTransform = async (sharp, request) => {
49
+ let img = sharp(request.bytes);
50
+ if (request.rotate) img = img.rotate(request.rotate);
51
+ if (request.flip?.vertical) img = img.flip();
52
+ if (request.flip?.horizontal) img = img.flop();
53
+ if (request.resize && (request.resize.width !== void 0 || request.resize.height !== void 0)) img = img.resize({
54
+ width: request.resize.width,
55
+ height: request.resize.height,
56
+ fit: request.resize.fit ?? "cover"
57
+ });
58
+ const target = request.format?.to ?? mimeToFormat(request.mimeType);
59
+ const mimeType = MIME_BY_FORMAT[target];
60
+ if (!mimeType) throw new Error(`sharp cannot encode "${target}"; supported: ${SUPPORTED_OUTPUT.join(", ")}`);
61
+ const formatKey = target === "jpg" ? "jpeg" : target;
62
+ img = img.toFormat(formatKey, request.format?.quality !== void 0 ? { quality: request.format.quality } : {});
63
+ if (request.stripMetadata !== true) img = img.keepMetadata();
64
+ const buffer = await img.toBuffer();
65
+ return {
66
+ bytes: new Uint8Array(buffer),
67
+ mimeType
68
+ };
69
+ };
70
+ /** Build the single mutate capability over a sharp source. */
71
+ var capabilityOf = (run) => ({
72
+ over: ["image/*"],
73
+ ops: [
74
+ "resize",
75
+ "rotate",
76
+ "flip",
77
+ "strip_metadata"
78
+ ],
79
+ encodes: SUPPORTED_OUTPUT,
80
+ mutate: run
81
+ });
82
+ /**
83
+ * Construct the sharp-backed image engine.
84
+ *
85
+ * @param options - Optional module resolver override.
86
+ * @returns The engine.
87
+ */
88
+ var sharpEngine = (options = {}) => {
89
+ let sharpPromise;
90
+ const getSharp = () => {
91
+ sharpPromise ??= resolveSharp(options.sharp);
92
+ return sharpPromise;
93
+ };
94
+ return {
95
+ id: "sharp",
96
+ mutates: [capabilityOf(async (request) => runTransform(await getSharp(), request))]
97
+ };
98
+ };
99
+ /**
100
+ * Adapt an already-configured sharp module (your import, your build flags) to the engine
101
+ * contract — the BYO transformer.
102
+ *
103
+ * @param sharp - The sharp function you imported.
104
+ * @returns The engine.
105
+ */
106
+ var fromSharp = (sharp) => ({
107
+ id: "sharp",
108
+ mutates: [capabilityOf(async (request) => runTransform(sharp, request))]
109
+ });
110
+ var mimeToFormat = (mimeType) => {
111
+ const sub = mimeType.toLowerCase().split(";")[0].trim().split("/")[1] ?? "png";
112
+ return sub === "jpeg" ? "jpg" : sub;
113
+ };
114
+ //#endregion
115
+ export { fromSharp, sharpEngine };
116
+
117
+ //# sourceMappingURL=sharp.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharp.mjs","names":[],"sources":["../../../../src/batteries/media/engines/sharp.ts"],"sourcesContent":["/**\n * A Node-native image {@link @nhtio/adk/batteries/media/contracts!MediaEngine}\n * backed by sharp (libvips bindings — fast, full-format).\n *\n * @module @nhtio/adk/batteries/media/engines/sharp\n *\n * @remarks\n * The performance/fidelity engine for Node deployments: native speed plus webp/avif output\n * and the full `fit` mode set. sharp is permanently Node-only (native bindings); for a\n * cross-environment engine compose the jimp implementation instead — the capability\n * declaration is the seam, and BYO instances adapt via {@link fromSharp}.\n *\n * `sharp` is an optional peer dependency, lazily imported on first actual use.\n */\n\nimport { isError } from '@nhtio/adk/guards'\nimport { default as SharpDefault } from 'sharp'\nimport { E_INVALID_MEDIA_PIPELINE_CONFIG } from '../exceptions'\nimport type { MediaEngine, MutateCapability, MutateRequest, EngineBytesResult } from '../contracts'\n\ntype SharpFn = typeof SharpDefault\n\n/** Options for {@link sharpEngine}. */\nexport interface SharpEngineOptions {\n /** Override the module resolution (electron/custom builds). Default: `import('sharp')`. */\n sharp?: () => SharpFn | { default: SharpFn } | Promise<SharpFn | { default: SharpFn }>\n}\n\nconst SUPPORTED_OUTPUT = ['png', 'jpg', 'jpeg', 'webp', 'tiff', 'avif', 'gif'] as const\n\nconst MIME_BY_FORMAT: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n webp: 'image/webp',\n tiff: 'image/tiff',\n avif: 'image/avif',\n gif: 'image/gif',\n}\n\nconst resolveSharp = async (supplied: SharpEngineOptions['sharp']): Promise<SharpFn> => {\n try {\n const mod = await (supplied ? supplied() : import('sharp'))\n const fn = typeof mod === 'function' ? mod : (mod as { default: SharpFn }).default\n if (typeof fn !== 'function') throw new Error('sharp did not resolve to a function')\n return fn\n } catch (err) {\n const detail = isError(err) ? err.message : String(err)\n throw new E_INVALID_MEDIA_PIPELINE_CONFIG([\n `the sharp engine could not load its peer dependency \"sharp\": ${detail} — install it (pnpm add sharp); note sharp is Node-only`,\n ])\n }\n}\n\n/** Run a fused mutate request through a sharp instance function. */\nconst runTransform = async (sharp: SharpFn, request: MutateRequest): Promise<EngineBytesResult> => {\n let img = sharp(request.bytes)\n if (request.rotate) img = img.rotate(request.rotate)\n if (request.flip?.vertical) img = img.flip()\n if (request.flip?.horizontal) img = img.flop()\n if (\n request.resize &&\n (request.resize.width !== undefined || request.resize.height !== undefined)\n ) {\n img = img.resize({\n width: request.resize.width,\n height: request.resize.height,\n fit: request.resize.fit ?? 'cover',\n })\n }\n const target = request.format?.to ?? mimeToFormat(request.mimeType)\n const mimeType = MIME_BY_FORMAT[target]\n if (!mimeType) {\n throw new Error(`sharp cannot encode \"${target}\"; supported: ${SUPPORTED_OUTPUT.join(', ')}`)\n }\n const formatKey = (target === 'jpg' ? 'jpeg' : target) as\n | 'png'\n | 'jpeg'\n | 'webp'\n | 'tiff'\n | 'avif'\n | 'gif'\n img = img.toFormat(\n formatKey,\n request.format?.quality !== undefined ? { quality: request.format.quality } : {}\n )\n if (request.stripMetadata !== true) {\n // sharp strips metadata by default; keep it when NOT asked to strip.\n img = img.keepMetadata()\n }\n const buffer = await img.toBuffer()\n return { bytes: new Uint8Array(buffer), mimeType }\n}\n\n/** Build the single mutate capability over a sharp source. */\nconst capabilityOf = (\n run: (request: MutateRequest) => Promise<EngineBytesResult>\n): MutateCapability => ({\n over: ['image/*'],\n ops: ['resize', 'rotate', 'flip', 'strip_metadata'],\n encodes: SUPPORTED_OUTPUT,\n mutate: run,\n})\n\n/**\n * Construct the sharp-backed image engine.\n *\n * @param options - Optional module resolver override.\n * @returns The engine.\n */\nexport const sharpEngine = (options: SharpEngineOptions = {}): MediaEngine => {\n let sharpPromise: Promise<SharpFn> | undefined\n const getSharp = (): Promise<SharpFn> => {\n sharpPromise ??= resolveSharp(options.sharp)\n return sharpPromise\n }\n return {\n id: 'sharp',\n mutates: [capabilityOf(async (request) => runTransform(await getSharp(), request))],\n }\n}\n\n/**\n * Adapt an already-configured sharp module (your import, your build flags) to the engine\n * contract — the BYO transformer.\n *\n * @param sharp - The sharp function you imported.\n * @returns The engine.\n */\nexport const fromSharp = (sharp: SharpFn): MediaEngine => ({\n id: 'sharp',\n mutates: [capabilityOf(async (request) => runTransform(sharp, request))],\n})\n\nconst mimeToFormat = (mimeType: string): string => {\n const sub = mimeType.toLowerCase().split(';')[0].trim().split('/')[1] ?? 'png'\n return sub === 'jpeg' ? 'jpg' : sub\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA4BA,IAAM,mBAAmB;CAAC;CAAO;CAAO;CAAQ;CAAQ;CAAQ;CAAQ;AAAK;AAE7E,IAAM,iBAAyC;CAC7C,KAAK;CACL,KAAK;CACL,MAAM;CACN,MAAM;CACN,MAAM;CACN,MAAM;CACN,KAAK;AACP;AAEA,IAAM,eAAe,OAAO,aAA4D;CACtF,IAAI;EACF,MAAM,MAAM,OAAO,WAAW,SAAS,IAAI,OAAO;EAClD,MAAM,KAAK,OAAO,QAAQ,aAAa,MAAO,IAA6B;EAC3E,IAAI,OAAO,OAAO,YAAY,MAAM,IAAI,MAAM,qCAAqC;EACnF,OAAO;CACT,SAAS,KAAK;EAEZ,MAAM,IAAI,gCAAgC,CACxC,gEAFa,QAAQ,GAAG,IAAI,IAAI,UAAU,OAAO,GAAG,EAEmB,wDACzE,CAAC;CACH;AACF;;AAGA,IAAM,eAAe,OAAO,OAAgB,YAAuD;CACjG,IAAI,MAAM,MAAM,QAAQ,KAAK;CAC7B,IAAI,QAAQ,QAAQ,MAAM,IAAI,OAAO,QAAQ,MAAM;CACnD,IAAI,QAAQ,MAAM,UAAU,MAAM,IAAI,KAAK;CAC3C,IAAI,QAAQ,MAAM,YAAY,MAAM,IAAI,KAAK;CAC7C,IACE,QAAQ,WACP,QAAQ,OAAO,UAAU,KAAA,KAAa,QAAQ,OAAO,WAAW,KAAA,IAEjE,MAAM,IAAI,OAAO;EACf,OAAO,QAAQ,OAAO;EACtB,QAAQ,QAAQ,OAAO;EACvB,KAAK,QAAQ,OAAO,OAAO;CAC7B,CAAC;CAEH,MAAM,SAAS,QAAQ,QAAQ,MAAM,aAAa,QAAQ,QAAQ;CAClE,MAAM,WAAW,eAAe;CAChC,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,wBAAwB,OAAO,gBAAgB,iBAAiB,KAAK,IAAI,GAAG;CAE9F,MAAM,YAAa,WAAW,QAAQ,SAAS;CAO/C,MAAM,IAAI,SACR,WACA,QAAQ,QAAQ,YAAY,KAAA,IAAY,EAAE,SAAS,QAAQ,OAAO,QAAQ,IAAI,CAAC,CACjF;CACA,IAAI,QAAQ,kBAAkB,MAE5B,MAAM,IAAI,aAAa;CAEzB,MAAM,SAAS,MAAM,IAAI,SAAS;CAClC,OAAO;EAAE,OAAO,IAAI,WAAW,MAAM;EAAG;CAAS;AACnD;;AAGA,IAAM,gBACJ,SACsB;CACtB,MAAM,CAAC,SAAS;CAChB,KAAK;EAAC;EAAU;EAAU;EAAQ;CAAgB;CAClD,SAAS;CACT,QAAQ;AACV;;;;;;;AAQA,IAAa,eAAe,UAA8B,CAAC,MAAmB;CAC5E,IAAI;CACJ,MAAM,iBAAmC;EACvC,iBAAiB,aAAa,QAAQ,KAAK;EAC3C,OAAO;CACT;CACA,OAAO;EACL,IAAI;EACJ,SAAS,CAAC,aAAa,OAAO,YAAY,aAAa,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC;CACpF;AACF;;;;;;;;AASA,IAAa,aAAa,WAAiC;CACzD,IAAI;CACJ,SAAS,CAAC,aAAa,OAAO,YAAY,aAAa,OAAO,OAAO,CAAC,CAAC;AACzE;AAEA,IAAM,gBAAgB,aAA6B;CACjD,MAAM,MAAM,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM;CACzE,OAAO,QAAQ,SAAS,QAAQ;AAClC"}