img-upload-kit 1.1.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +56 -41
  2. package/MIGRATION.md +192 -0
  3. package/README.md +138 -154
  4. package/dist/bin.js +1186 -0
  5. package/dist/bin.js.map +1 -0
  6. package/dist/blur.cjs +40 -412
  7. package/dist/blur.cjs.map +1 -1
  8. package/dist/blur.d.cts +5 -5
  9. package/dist/blur.d.ts +5 -5
  10. package/dist/blur.js +39 -393
  11. package/dist/blur.js.map +1 -1
  12. package/dist/blurDataUtils-DveBRtqE.d.cts +43 -0
  13. package/dist/blurDataUtils-yx9Q6HlU.d.ts +43 -0
  14. package/dist/blurService-D5TpMNji.d.ts +83 -0
  15. package/dist/blurService-DacwylJx.d.cts +83 -0
  16. package/dist/chunk-2OVNXHTN.cjs +514 -0
  17. package/dist/chunk-2OVNXHTN.cjs.map +1 -0
  18. package/dist/chunk-3ICG2SLL.cjs +135 -0
  19. package/dist/chunk-3ICG2SLL.cjs.map +1 -0
  20. package/dist/chunk-4ASFG3KB.js +514 -0
  21. package/dist/chunk-4ASFG3KB.js.map +1 -0
  22. package/dist/chunk-AI3JJLSA.js +2370 -0
  23. package/dist/chunk-AI3JJLSA.js.map +1 -0
  24. package/dist/chunk-CV23O4YU.js +145 -0
  25. package/dist/chunk-CV23O4YU.js.map +1 -0
  26. package/dist/chunk-G7LLSKBV.js +158 -0
  27. package/dist/chunk-G7LLSKBV.js.map +1 -0
  28. package/dist/chunk-IB3TEDLR.js +294 -0
  29. package/dist/chunk-IB3TEDLR.js.map +1 -0
  30. package/dist/chunk-KJVYWKIG.cjs +158 -0
  31. package/dist/chunk-KJVYWKIG.cjs.map +1 -0
  32. package/dist/chunk-NEDBIIE3.cjs +226 -0
  33. package/dist/chunk-NEDBIIE3.cjs.map +1 -0
  34. package/dist/chunk-QHU7FUO4.cjs +37 -0
  35. package/dist/chunk-QHU7FUO4.cjs.map +1 -0
  36. package/dist/chunk-QQHZJKNA.js +135 -0
  37. package/dist/chunk-QQHZJKNA.js.map +1 -0
  38. package/dist/chunk-S2IFAWJK.js +37 -0
  39. package/dist/chunk-S2IFAWJK.js.map +1 -0
  40. package/dist/chunk-TT5C7K3Q.js +226 -0
  41. package/dist/chunk-TT5C7K3Q.js.map +1 -0
  42. package/dist/chunk-U2TWTEBY.cjs +2370 -0
  43. package/dist/chunk-U2TWTEBY.cjs.map +1 -0
  44. package/dist/chunk-WISG74VL.cjs +294 -0
  45. package/dist/chunk-WISG74VL.cjs.map +1 -0
  46. package/dist/chunk-YRXXQUDE.cjs +145 -0
  47. package/dist/chunk-YRXXQUDE.cjs.map +1 -0
  48. package/dist/cli.cjs +273 -76
  49. package/dist/cli.cjs.map +1 -1
  50. package/dist/cli.js +269 -73
  51. package/dist/cli.js.map +1 -1
  52. package/dist/headless.cjs +8 -1880
  53. package/dist/headless.cjs.map +1 -1
  54. package/dist/headless.d.cts +3 -1
  55. package/dist/headless.d.ts +3 -1
  56. package/dist/headless.js +25 -1886
  57. package/dist/headless.js.map +1 -1
  58. package/dist/index-BIdnqtW8.d.ts +234 -0
  59. package/dist/index-Brk_uHs6.d.cts +234 -0
  60. package/dist/{index-FVXXKf2v.d.ts → index-CPMlaQsC.d.ts} +76 -153
  61. package/dist/{index-FVXXKf2v.d.cts → index-DHINe-rA.d.cts} +76 -153
  62. package/dist/index.cjs +64 -532
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.d.cts +7 -4
  65. package/dist/index.d.ts +7 -4
  66. package/dist/index.js +63 -504
  67. package/dist/index.js.map +1 -1
  68. package/dist/{memoryAdapter-CBu7_3Pp.d.ts → memoryAdapter-Ck0ccZbF.d.cts} +3 -2
  69. package/dist/{memoryAdapter-BJjyLR-1.d.cts → memoryAdapter-DxEKaG0b.d.ts} +3 -2
  70. package/dist/placeholders-C4ftwaII.d.ts +5 -0
  71. package/dist/placeholders-x_3rt65M.d.cts +5 -0
  72. package/dist/react.cjs +1952 -3257
  73. package/dist/react.cjs.map +1 -1
  74. package/dist/react.d.cts +188 -50
  75. package/dist/react.d.ts +188 -50
  76. package/dist/react.js +1763 -3013
  77. package/dist/react.js.map +1 -1
  78. package/dist/server-handler.cjs +14 -0
  79. package/dist/server-handler.cjs.map +1 -0
  80. package/dist/server-handler.d.cts +3 -0
  81. package/dist/server-handler.d.ts +3 -0
  82. package/dist/server-handler.js +14 -0
  83. package/dist/server-handler.js.map +1 -0
  84. package/dist/server.cjs +1096 -532
  85. package/dist/server.cjs.map +1 -1
  86. package/dist/server.d.cts +77 -154
  87. package/dist/server.d.ts +77 -154
  88. package/dist/server.js +1050 -448
  89. package/dist/server.js.map +1 -1
  90. package/dist/storage.cjs +239 -232
  91. package/dist/storage.cjs.map +1 -1
  92. package/dist/storage.d.cts +21 -5
  93. package/dist/storage.d.ts +21 -5
  94. package/dist/storage.js +227 -207
  95. package/dist/storage.js.map +1 -1
  96. package/dist/styles/animated-image.css +112 -0
  97. package/dist/styles/dropzone-and-tiles.css +247 -0
  98. package/dist/styles/modals-and-dock.css +248 -0
  99. package/dist/styles/primitives.css +197 -0
  100. package/dist/styles/quality-and-inputs.css +184 -0
  101. package/dist/styles/tokens.css +123 -0
  102. package/dist/styles.css +39 -24
  103. package/dist/types-BrP-o9nd.d.cts +85 -0
  104. package/dist/types-sZ3KoFQY.d.ts +85 -0
  105. package/dist/types-yShGNQnW.d.cts +61 -0
  106. package/dist/types-yShGNQnW.d.ts +61 -0
  107. package/dist/{types-CiLY0DwB.d.cts → upload-C5Trd6Dh.d.cts} +27 -53
  108. package/dist/{types-CiLY0DwB.d.ts → upload-C5Trd6Dh.d.ts} +27 -53
  109. package/package.json +92 -32
  110. package/dist/blurService-DqsnfPTd.d.cts +0 -172
  111. package/dist/blurService-DqsnfPTd.d.ts +0 -172
package/dist/blur.cjs CHANGED
@@ -1,413 +1,41 @@
1
- 'use strict';
2
-
3
- var blurhash = require('blurhash');
4
-
5
- // src/blur/blurDataUtils.ts
6
- function getBlurData(image) {
7
- if (!image) {
8
- return {
9
- blurDataUrl: "",
10
- blurColor: "#E5E7EB",
11
- hasBlur: false
12
- };
13
- }
14
- return {
15
- blurDataUrl: image.blurDataUrl || "",
16
- blurColor: image.blurColor || "#E5E7EB",
17
- ...image.blurHash ? { blurHash: image.blurHash } : {},
18
- hasBlur: Boolean(image.blurDataUrl || image.blurHash)
19
- };
20
- }
21
- function getImagePropsWithBlur(image) {
22
- if (!image?.url) {
23
- return null;
24
- }
25
- const blurData = getBlurData(image);
26
- return {
27
- src: image.url,
28
- alt: image.altText || "",
29
- width: image.width || 1920,
30
- height: image.height || 1080,
31
- ...blurData.blurDataUrl && {
32
- placeholder: "blur",
33
- blurDataURL: blurData.blurDataUrl
34
- }
35
- };
36
- }
37
- function getBackgroundPropsWithBlur(image) {
38
- if (!image?.url) {
39
- return {
40
- backgroundColor: "#E5E7EB"
41
- };
42
- }
43
- const blurData = getBlurData(image);
44
- return {
45
- backgroundColor: blurData.blurColor,
46
- backgroundImage: `url(${image.url})`,
47
- backgroundSize: "cover",
48
- backgroundPosition: "center",
49
- backgroundRepeat: "no-repeat"
50
- };
51
- }
52
- function getBlurPlaceholderStyle(image) {
53
- const blurData = getBlurData(image);
54
- if (!blurData.blurDataUrl) {
55
- return {
56
- backgroundColor: blurData.blurColor
57
- };
58
- }
59
- return {
60
- backgroundColor: blurData.blurColor,
61
- backgroundImage: `url(${blurData.blurDataUrl})`,
62
- backgroundSize: "cover",
63
- backgroundPosition: "center",
64
- filter: "blur(20px)",
65
- transform: "scale(1.1)"
66
- };
67
- }
68
- function hasBlurData(image) {
69
- return Boolean(image?.blurDataUrl || image?.blurColor || image?.blurHash);
70
- }
71
- function getBulkBlurData(images) {
72
- return images.map(getBlurData);
73
- }
74
- function createSrcSetWithBlur(image) {
75
- if (!image?.url) return "";
76
- const blurData = getBlurData(image);
77
- if (!blurData.blurDataUrl) {
78
- return image.url;
79
- }
80
- return `${blurData.blurDataUrl} 40w, ${image.url} ${image.width || 1920}w`;
81
- }
82
- function preloadImageWithBlur(image) {
83
- if (!image?.url || typeof document === "undefined") return;
84
- const link = document.createElement("link");
85
- link.rel = "preload";
86
- link.as = "image";
87
- link.href = image.url;
88
- const blurData = getBlurData(image);
89
- if (blurData.blurDataUrl) {
90
- link.setAttribute("imagesrcset", blurData.blurDataUrl);
91
- }
92
- document.head.appendChild(link);
93
- }
94
- function extractImageUrls(image) {
95
- if (!image?.url) return [];
96
- return [image.url];
97
- }
98
- function decodeBlurHashToDataURL(hash, width = 32, height = 32, punch = 1) {
99
- if (!hash || typeof document === "undefined") return null;
100
- const validation = blurhash.isBlurhashValid(hash);
101
- if (!validation.result) return null;
102
- try {
103
- const pixels = blurhash.decode(hash, width, height, punch);
104
- const canvas = document.createElement("canvas");
105
- canvas.width = width;
106
- canvas.height = height;
107
- const ctx = canvas.getContext("2d");
108
- if (!ctx) return null;
109
- const imageData = ctx.createImageData(width, height);
110
- imageData.data.set(pixels);
111
- ctx.putImageData(imageData, 0, 0);
112
- return canvas.toDataURL("image/png");
113
- } catch {
114
- return null;
115
- }
116
- }
117
-
118
- // src/blur/lruCache.ts
119
- var LRUCache = class {
120
- maxSize;
121
- cache;
122
- constructor(maxSize = 500) {
123
- this.maxSize = Math.max(1, maxSize);
124
- this.cache = /* @__PURE__ */ new Map();
125
- }
126
- get(key) {
127
- if (!this.cache.has(key)) return void 0;
128
- const value = this.cache.get(key);
129
- this.cache.delete(key);
130
- this.cache.set(key, value);
131
- return value;
132
- }
133
- set(key, value) {
134
- if (this.cache.has(key)) {
135
- this.cache.delete(key);
136
- }
137
- if (this.cache.size >= this.maxSize) {
138
- const firstKey = this.cache.keys().next().value;
139
- if (firstKey !== void 0) {
140
- this.cache.delete(firstKey);
141
- }
142
- }
143
- this.cache.set(key, value);
144
- }
145
- has(key) {
146
- return this.cache.has(key);
147
- }
148
- clear() {
149
- this.cache.clear();
150
- }
151
- get size() {
152
- return this.cache.size;
153
- }
154
- };
155
-
156
- // src/blur/pathMapper.ts
157
- var DEFAULT_CDN_PATTERNS = [
158
- /^https?:\/\/[^/]+\.supabase\.co\/storage\/v1\/object\/public\/([^/]+)\/(.+)$/,
159
- /^https?:\/\/[^/]+\.r2\.dev\/(.+)$/,
160
- /^https?:\/\/[^/]+\.amazonaws\.com\/(.+)$/,
161
- /^https?:\/\/[^/]+\.cloudflare\.com\/(.+)$/,
162
- /^https?:\/\/cdn\.[^/]+\/(.+)$/
163
- ];
164
- function normalizeImagePath(imageSrc, options = {}) {
165
- const originalPath = imageSrc;
166
- let normalizedPath = imageSrc;
167
- let isExternal = false;
168
- try {
169
- if (imageSrc.startsWith("data:") || imageSrc.startsWith("blob:")) {
170
- return {
171
- normalizedPath: imageSrc,
172
- isExternal: false,
173
- originalPath
174
- };
175
- }
176
- const patterns = options.cdnPatterns || DEFAULT_CDN_PATTERNS;
177
- if (imageSrc.startsWith("http://") || imageSrc.startsWith("https://")) {
178
- const url = new URL(imageSrc);
179
- isExternal = true;
180
- const cleanUrlNoQuery = `${url.origin}${url.pathname}`;
181
- for (const pattern of patterns) {
182
- const match = cleanUrlNoQuery.match(pattern);
183
- if (match) {
184
- const pathPart = match[match.length - 1];
185
- normalizedPath = "/" + pathPart.replace(/^\/+/, "");
186
- break;
187
- }
188
- }
189
- if (normalizedPath === imageSrc) {
190
- normalizedPath = url.pathname;
191
- }
192
- } else {
193
- normalizedPath = normalizedPath.split("?")[0].split("#")[0];
194
- }
195
- normalizedPath = normalizedPath.replace(/\\/g, "/").replace(/^\.\.?\//g, "");
196
- if (!normalizedPath.startsWith("/")) {
197
- normalizedPath = "/" + normalizedPath;
198
- }
199
- const prefixesToStrip = options.stripPrefixes || ["/public/"];
200
- for (const prefix of prefixesToStrip) {
201
- if (normalizedPath.startsWith(prefix)) {
202
- normalizedPath = "/" + normalizedPath.slice(prefix.length).replace(/^\/+/, "");
203
- }
204
- }
205
- const segments = normalizedPath.split("/").filter(Boolean);
206
- const filename = segments[segments.length - 1];
207
- const folder = segments.length > 1 ? segments.slice(0, -1).join("/") : void 0;
208
- const dotIdx = filename ? filename.lastIndexOf(".") : -1;
209
- const extension = filename && dotIdx > 0 ? filename.slice(dotIdx + 1).toLowerCase() : void 0;
210
- return {
211
- normalizedPath,
212
- folder,
213
- filename,
214
- extension,
215
- isExternal,
216
- originalPath
217
- };
218
- } catch {
219
- return {
220
- normalizedPath: imageSrc,
221
- isExternal: false,
222
- originalPath
223
- };
224
- }
225
- }
226
-
227
- // src/blur/placeholders.ts
228
- var DEFAULT_PLACEHOLDERS = {
229
- default: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDE1MCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkaWVudCIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzJhMzIzZDtzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iNTAlIiBzdHlsZT0ic3RvcC1jb2xvcjojMjEyNzMwO3N0b3Atb3BhY2l0eToxIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdHlsZT0ic3RvcC1jb2xvcjojMTgxZDI0O3N0b3Atb3BhY2l0eToxIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3Qgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxNTAiIGZpbGw9InVybCgjZ3JhZGllbnQpIi8+PC9zdmc+",
230
- hero: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTkyMCIgaGVpZ2h0PSIxMDgwIiB2aWV3Qm94PSIwIDAgMTkyMCAxMDgwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0iaGVyb0dyYWRpZW50IiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdHlsZT0ic3RvcC1jb2xvcjojMmQzNzQ4O3N0b3Atb3BhY2l0eToxIi8+PHN0b3Agb2Zmc2V0PSIzMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiMyMzJiMzg7c3RvcC1vcGFjaXR5OjEiLz48c3RvcCBvZmZzZXQ9IjcwJSIgc3R5bGU9InN0b3AtY29sb3I6IzFlMjUzMDtzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6IzE3MWQyNztzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHdpZHRoPSIxOTIwIiBoZWlnaHQ9IjEwODAiIGZpbGw9InVybCgjaGVyb0dyYWRpZW50KSIvPjwvc3ZnPg==",
231
- card: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDQwMCAzMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJjYXJkR3JhZGllbnQiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiMyYTMyM2Q7c3RvcC1vcGFjaXR5OjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiMxYzIyMmI7c3RvcC1vcGFjaXR5OjEiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgZmlsbD0idXJsKCNjYXJkR3JhZGllbnQpIi8+PC9zdmc+",
232
- thumbnail: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIGZpbGw9IiMyNDJiMzUiLz48L3N2Zz4="
233
- };
234
-
235
- // src/blur/blurService.ts
236
- var BlurService = class {
237
- blurData;
238
- cache;
239
- pathOptions;
240
- metadata;
241
- metrics;
242
- constructor(options = {}) {
243
- this.blurData = {};
244
- this.pathOptions = options.pathOptions;
245
- this.metadata = {
246
- version: "2.0",
247
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
248
- totalImages: 0
249
- };
250
- this.cache = new LRUCache(options.cacheSize ?? 500);
251
- this.metrics = {
252
- totalRequests: 0,
253
- cacheHits: 0,
254
- cacheMisses: 0,
255
- errors: 0
256
- };
257
- if (options.manifest) {
258
- this.loadManifest(options.manifest);
259
- }
260
- }
261
- /**
262
- * Hydrate the service with a generated `blur-hashes.json` manifest or hash map.
263
- */
264
- loadManifest(manifest) {
265
- this.cache.clear();
266
- if ("hashes" in manifest && typeof manifest.hashes === "object" && manifest.hashes !== null) {
267
- const typed = manifest;
268
- this.blurData = { ...typed.hashes };
269
- this.metadata = {
270
- version: typed.version || "2.0",
271
- generatedAt: typed.generatedAt || (/* @__PURE__ */ new Date()).toISOString(),
272
- totalImages: Object.keys(this.blurData).length
273
- };
274
- } else {
275
- this.blurData = { ...manifest };
276
- this.metadata = {
277
- version: "2.0",
278
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
279
- totalImages: Object.keys(this.blurData).length
280
- };
281
- }
282
- }
283
- /**
284
- * Register or update a single image's blur data at runtime.
285
- */
286
- registerEntry(imagePath, entry) {
287
- this.blurData[imagePath] = entry;
288
- this.metadata.totalImages = Object.keys(this.blurData).length;
289
- this.cache.clear();
290
- }
291
- getDefaultPlaceholder(type = "default") {
292
- return DEFAULT_PLACEHOLDERS[type];
293
- }
294
- findBlurDataByPath(imageSrc) {
295
- let data = this.blurData[imageSrc];
296
- if (data) return data;
297
- const pathInfo = normalizeImagePath(imageSrc, this.pathOptions);
298
- data = this.blurData[pathInfo.normalizedPath];
299
- if (data) return data;
300
- const withSlash = pathInfo.normalizedPath.startsWith("/") ? pathInfo.normalizedPath : "/" + pathInfo.normalizedPath;
301
- const withoutSlash = pathInfo.normalizedPath.replace(/^\/+/, "");
302
- data = this.blurData[withSlash] || this.blurData[withoutSlash];
303
- if (data) return data;
304
- if (pathInfo.isExternal && pathInfo.originalPath !== imageSrc) {
305
- data = this.blurData[pathInfo.originalPath];
306
- if (data) return data;
307
- }
308
- return null;
309
- }
310
- getDominantColor(imageSrc) {
311
- const data = this.findBlurDataByPath(imageSrc);
312
- return data?.color || "#E5E7EB";
313
- }
314
- getBlurDataURL(imageSrc, options = {}) {
315
- const { type = "default", size = "small" } = options;
316
- this.metrics.totalRequests++;
317
- const cacheKey = `${imageSrc}-${size}`;
318
- if (this.cache.has(cacheKey)) {
319
- this.metrics.cacheHits++;
320
- return this.cache.get(cacheKey).dataUrl;
321
- }
322
- this.metrics.cacheMisses++;
323
- if (Object.keys(this.blurData).length === 0) {
324
- return this.getDefaultPlaceholder(type);
325
- }
326
- const data = this.findBlurDataByPath(imageSrc);
327
- if (!data) {
328
- return this.getDefaultPlaceholder(type);
329
- }
330
- const blurDataURL = data.variants?.[size] || data.variants?.small || this.getDefaultPlaceholder(type);
331
- this.cache.set(cacheKey, {
332
- dataUrl: blurDataURL,
333
- timestamp: Date.now()
334
- });
335
- return blurDataURL;
336
- }
337
- getBulkBlurData(imageSrcs, options = {}) {
338
- const result = {};
339
- for (const imageSrc of imageSrcs) {
340
- result[imageSrc] = this.getBlurDataURL(imageSrc, options);
341
- }
342
- return result;
343
- }
344
- getProgressiveData(imageSrc, size = "small") {
345
- return {
346
- color: this.getDominantColor(imageSrc),
347
- blur: this.getBlurDataURL(imageSrc, { size }),
348
- hasBlur: this.hasBlurHash(imageSrc)
349
- };
350
- }
351
- hasBlurHash(imageSrc) {
352
- return Boolean(this.findBlurDataByPath(imageSrc));
353
- }
354
- getMetadata() {
355
- const cacheHitRate = this.metrics.totalRequests > 0 ? (this.metrics.cacheHits / this.metrics.totalRequests * 100).toFixed(2) : "0.00";
356
- return {
357
- ...this.metadata,
358
- cacheSize: this.cache.size,
359
- metrics: {
360
- ...this.metrics,
361
- cacheHitRate: `${cacheHitRate}%`
362
- }
363
- };
364
- }
365
- clearCache() {
366
- this.cache.clear();
367
- }
368
- getBlurHash(imageSrc) {
369
- const data = this.findBlurDataByPath(imageSrc);
370
- return data?.hash || null;
371
- }
372
- preloadBlurData(imageSrcs, size = "small") {
373
- for (const imageSrc of imageSrcs) {
374
- this.getBlurDataURL(imageSrc, { size });
375
- }
376
- }
377
- async fetchBlurDataForImage(imageSrc, type = "default") {
378
- return Promise.resolve(this.getBlurDataURL(imageSrc, { type }));
379
- }
380
- getAvailableKeys() {
381
- return Object.keys(this.blurData);
382
- }
383
- findMatchingKeys(searchTerm) {
384
- const lower = searchTerm.toLowerCase();
385
- return Object.keys(this.blurData).filter(
386
- (key) => key.toLowerCase().includes(lower)
387
- );
388
- }
389
- };
390
- function createBlurService(options) {
391
- return new BlurService(options);
392
- }
393
- var blurService = new BlurService();
394
-
395
- exports.BlurService = BlurService;
396
- exports.DEFAULT_CDN_PATTERNS = DEFAULT_CDN_PATTERNS;
397
- exports.DEFAULT_PLACEHOLDERS = DEFAULT_PLACEHOLDERS;
398
- exports.LRUCache = LRUCache;
399
- exports.blurService = blurService;
400
- exports.createBlurService = createBlurService;
401
- exports.createSrcSetWithBlur = createSrcSetWithBlur;
402
- exports.decodeBlurHashToDataURL = decodeBlurHashToDataURL;
403
- exports.extractImageUrls = extractImageUrls;
404
- exports.getBackgroundPropsWithBlur = getBackgroundPropsWithBlur;
405
- exports.getBlurData = getBlurData;
406
- exports.getBlurPlaceholderStyle = getBlurPlaceholderStyle;
407
- exports.getBulkBlurData = getBulkBlurData;
408
- exports.getImagePropsWithBlur = getImagePropsWithBlur;
409
- exports.hasBlurData = hasBlurData;
410
- exports.normalizeImagePath = normalizeImagePath;
411
- exports.preloadImageWithBlur = preloadImageWithBlur;
412
- //# sourceMappingURL=blur.cjs.map
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+ var _chunkWISG74VLcjs = require('./chunk-WISG74VL.cjs');
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+ var _chunk3ICG2SLLcjs = require('./chunk-3ICG2SLL.cjs');
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+ exports.BlurService = _chunkWISG74VLcjs.BlurService; exports.DEFAULT_CDN_PATTERNS = _chunkWISG74VLcjs.DEFAULT_CDN_PATTERNS; exports.DEFAULT_PLACEHOLDERS = _chunkWISG74VLcjs.DEFAULT_PLACEHOLDERS; exports.LRUCache = _chunkWISG74VLcjs.LRUCache; exports.blurService = _chunkWISG74VLcjs.blurService; exports.createBlurService = _chunkWISG74VLcjs.createBlurService; exports.createSrcSetWithBlur = _chunk3ICG2SLLcjs.createSrcSetWithBlur; exports.decodeBlurHashToDataURL = _chunk3ICG2SLLcjs.decodeBlurHashToDataURL; exports.extractImageUrls = _chunk3ICG2SLLcjs.extractImageUrls; exports.getBackgroundPropsWithBlur = _chunk3ICG2SLLcjs.getBackgroundPropsWithBlur; exports.getBlurData = _chunk3ICG2SLLcjs.getBlurData; exports.getBlurPlaceholderStyle = _chunk3ICG2SLLcjs.getBlurPlaceholderStyle; exports.getBulkBlurData = _chunk3ICG2SLLcjs.getBulkBlurData; exports.getImagePropsWithBlur = _chunk3ICG2SLLcjs.getImagePropsWithBlur; exports.hasBlurData = _chunk3ICG2SLLcjs.hasBlurData; exports.normalizeImagePath = _chunkWISG74VLcjs.normalizeImagePath; exports.preloadImageWithBlur = _chunk3ICG2SLLcjs.preloadImageWithBlur;
413
41
  //# sourceMappingURL=blur.cjs.map
package/dist/blur.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/blur/blurDataUtils.ts","../src/blur/lruCache.ts","../src/blur/pathMapper.ts","../src/blur/placeholders.ts","../src/blur/blurService.ts"],"names":["isBlurhashValid","decodeBlurHash"],"mappings":"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","file":"blur.cjs","sourcesContent":["import { decode as decodeBlurHash, isBlurhashValid } from 'blurhash';\nimport type { BlurData, BlurImageSource } from './types';\n\nexport interface BlurPlaceholderStyle {\n backgroundColor: string;\n backgroundImage?: string;\n backgroundSize?: string;\n backgroundPosition?: string;\n backgroundRepeat?: string;\n filter?: string;\n transform?: string;\n}\n\nexport function getBlurData(\n image: BlurImageSource | null | undefined,\n): BlurData {\n if (!image) {\n return {\n blurDataUrl: '',\n blurColor: '#E5E7EB',\n hasBlur: false,\n };\n }\n\n return {\n blurDataUrl: image.blurDataUrl || '',\n blurColor: image.blurColor || '#E5E7EB',\n ...(image.blurHash ? { blurHash: image.blurHash } : {}),\n hasBlur: Boolean(image.blurDataUrl || image.blurHash),\n };\n}\n\nexport function getImagePropsWithBlur(\n image: BlurImageSource | null | undefined,\n) {\n if (!image?.url) {\n return null;\n }\n\n const blurData = getBlurData(image);\n\n return {\n src: image.url,\n alt: image.altText || '',\n width: image.width || 1920,\n height: image.height || 1080,\n ...(blurData.blurDataUrl && {\n placeholder: 'blur' as const,\n blurDataURL: blurData.blurDataUrl,\n }),\n };\n}\n\nexport function getBackgroundPropsWithBlur(\n image: BlurImageSource | null | undefined,\n): BlurPlaceholderStyle {\n if (!image?.url) {\n return {\n backgroundColor: '#E5E7EB',\n };\n }\n\n const blurData = getBlurData(image);\n\n return {\n backgroundColor: blurData.blurColor,\n backgroundImage: `url(${image.url})`,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n backgroundRepeat: 'no-repeat',\n };\n}\n\nexport function getBlurPlaceholderStyle(\n image: BlurImageSource | null | undefined,\n): BlurPlaceholderStyle {\n const blurData = getBlurData(image);\n\n if (!blurData.blurDataUrl) {\n return {\n backgroundColor: blurData.blurColor,\n };\n }\n\n return {\n backgroundColor: blurData.blurColor,\n backgroundImage: `url(${blurData.blurDataUrl})`,\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n filter: 'blur(20px)',\n transform: 'scale(1.1)',\n };\n}\n\nexport function hasBlurData(\n image: BlurImageSource | null | undefined,\n): boolean {\n return Boolean(image?.blurDataUrl || image?.blurColor || image?.blurHash);\n}\n\nexport function getBulkBlurData(\n images: Array<BlurImageSource | null | undefined>,\n): BlurData[] {\n return images.map(getBlurData);\n}\n\nexport function createSrcSetWithBlur(\n image: BlurImageSource | null | undefined,\n): string {\n if (!image?.url) return '';\n\n const blurData = getBlurData(image);\n if (!blurData.blurDataUrl) {\n return image.url;\n }\n\n return `${blurData.blurDataUrl} 40w, ${image.url} ${image.width || 1920}w`;\n}\n\nexport function preloadImageWithBlur(\n image: BlurImageSource | null | undefined,\n): void {\n if (!image?.url || typeof document === 'undefined') return;\n\n const link = document.createElement('link');\n link.rel = 'preload';\n link.as = 'image';\n link.href = image.url;\n\n const blurData = getBlurData(image);\n if (blurData.blurDataUrl) {\n link.setAttribute('imagesrcset', blurData.blurDataUrl);\n }\n\n document.head.appendChild(link);\n}\n\nexport function extractImageUrls(\n image: BlurImageSource | null | undefined,\n): string[] {\n if (!image?.url) return [];\n return [image.url];\n}\n\n/**\n * Browser helper: Decodes a compact BlurHash string (e.g. \"LEHV6nWB2yk8pyo0adR*.7kCMdnj\")\n * into a `data:image/png;base64,...` URL using an offscreen `<canvas>`.\n */\nexport function decodeBlurHashToDataURL(\n hash: string,\n width: number = 32,\n height: number = 32,\n punch: number = 1,\n): string | null {\n if (!hash || typeof document === 'undefined') return null;\n const validation = isBlurhashValid(hash);\n if (!validation.result) return null;\n\n try {\n const pixels = decodeBlurHash(hash, width, height, punch);\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n const imageData = ctx.createImageData(width, height);\n imageData.data.set(pixels);\n ctx.putImageData(imageData, 0, 0);\n return canvas.toDataURL('image/png');\n } catch {\n return null;\n }\n}\n","export class LRUCache<K, V> {\n private readonly maxSize: number;\n private readonly cache: Map<K, V>;\n\n constructor(maxSize: number = 500) {\n this.maxSize = Math.max(1, maxSize);\n this.cache = new Map();\n }\n\n get(key: K): V | undefined {\n if (!this.cache.has(key)) return undefined;\n\n const value = this.cache.get(key)!;\n this.cache.delete(key);\n this.cache.set(key, value);\n return value;\n }\n\n set(key: K, value: V): void {\n if (this.cache.has(key)) {\n this.cache.delete(key);\n }\n\n if (this.cache.size >= this.maxSize) {\n const firstKey = this.cache.keys().next().value;\n if (firstKey !== undefined) {\n this.cache.delete(firstKey);\n }\n }\n\n this.cache.set(key, value);\n }\n\n has(key: K): boolean {\n return this.cache.has(key);\n }\n\n clear(): void {\n this.cache.clear();\n }\n\n get size(): number {\n return this.cache.size;\n }\n}\n","export const DEFAULT_CDN_PATTERNS: RegExp[] = [\n /^https?:\\/\\/[^/]+\\.supabase\\.co\\/storage\\/v1\\/object\\/public\\/([^/]+)\\/(.+)$/,\n /^https?:\\/\\/[^/]+\\.r2\\.dev\\/(.+)$/,\n /^https?:\\/\\/[^/]+\\.amazonaws\\.com\\/(.+)$/,\n /^https?:\\/\\/[^/]+\\.cloudflare\\.com\\/(.+)$/,\n /^https?:\\/\\/cdn\\.[^/]+\\/(.+)$/,\n];\n\nexport interface NormalizePathOptions {\n cdnPatterns?: RegExp[];\n stripPrefixes?: string[];\n}\n\nexport interface PathInfo {\n normalizedPath: string;\n folder?: string;\n filename?: string;\n extension?: string;\n isExternal: boolean;\n originalPath: string;\n}\n\n/**\n * Project-agnostic image URL / path normalizer.\n * Strips query parameters, leading `/public/`, relative `./`, and common CDN prefixes\n * so manifest keys match consistently across local and CDN environments.\n */\nexport function normalizeImagePath(\n imageSrc: string,\n options: NormalizePathOptions = {},\n): PathInfo {\n const originalPath = imageSrc;\n let normalizedPath = imageSrc;\n let isExternal = false;\n\n try {\n if (imageSrc.startsWith('data:') || imageSrc.startsWith('blob:')) {\n return {\n normalizedPath: imageSrc,\n isExternal: false,\n originalPath,\n };\n }\n\n const patterns = options.cdnPatterns || DEFAULT_CDN_PATTERNS;\n\n if (imageSrc.startsWith('http://') || imageSrc.startsWith('https://')) {\n const url = new URL(imageSrc);\n isExternal = true;\n const cleanUrlNoQuery = `${url.origin}${url.pathname}`;\n\n for (const pattern of patterns) {\n const match = cleanUrlNoQuery.match(pattern);\n if (match) {\n const pathPart = match[match.length - 1];\n normalizedPath = '/' + pathPart.replace(/^\\/+/, '');\n break;\n }\n }\n\n if (normalizedPath === imageSrc) {\n normalizedPath = url.pathname;\n }\n } else {\n normalizedPath = normalizedPath.split('?')[0].split('#')[0];\n }\n\n normalizedPath = normalizedPath.replace(/\\\\/g, '/').replace(/^\\.\\.?\\//g, '');\n\n if (!normalizedPath.startsWith('/')) {\n normalizedPath = '/' + normalizedPath;\n }\n\n const prefixesToStrip = options.stripPrefixes || ['/public/'];\n for (const prefix of prefixesToStrip) {\n if (normalizedPath.startsWith(prefix)) {\n normalizedPath = '/' + normalizedPath.slice(prefix.length).replace(/^\\/+/, '');\n }\n }\n\n const segments = normalizedPath.split('/').filter(Boolean);\n const filename = segments[segments.length - 1];\n const folder =\n segments.length > 1 ? segments.slice(0, -1).join('/') : undefined;\n const dotIdx = filename ? filename.lastIndexOf('.') : -1;\n const extension =\n filename && dotIdx > 0 ? filename.slice(dotIdx + 1).toLowerCase() : undefined;\n\n return {\n normalizedPath,\n folder,\n filename,\n extension,\n isExternal,\n originalPath,\n };\n } catch {\n return {\n normalizedPath: imageSrc,\n isExternal: false,\n originalPath,\n };\n }\n}\n","import type { BlurPlaceholderType } from './types';\n\nexport const DEFAULT_PLACEHOLDERS: Record<BlurPlaceholderType, string> = {\n default:\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDE1MCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkaWVudCIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzJhMzIzZDtzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iNTAlIiBzdHlsZT0ic3RvcC1jb2xvcjojMjEyNzMwO3N0b3Atb3BhY2l0eToxIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdHlsZT0ic3RvcC1jb2xvcjojMTgxZDI0O3N0b3Atb3BhY2l0eToxIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3Qgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxNTAiIGZpbGw9InVybCgjZ3JhZGllbnQpIi8+PC9zdmc+',\n hero:\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTkyMCIgaGVpZ2h0PSIxMDgwIiB2aWV3Qm94PSIwIDAgMTkyMCAxMDgwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0iaGVyb0dyYWRpZW50IiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdHlsZT0ic3RvcC1jb2xvcjojMmQzNzQ4O3N0b3Atb3BhY2l0eToxIi8+PHN0b3Agb2Zmc2V0PSIzMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiMyMzJiMzg7c3RvcC1vcGFjaXR5OjEiLz48c3RvcCBvZmZzZXQ9IjcwJSIgc3R5bGU9InN0b3AtY29sb3I6IzFlMjUzMDtzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6IzE3MWQyNztzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHdpZHRoPSIxOTIwIiBoZWlnaHQ9IjEwODAiIGZpbGw9InVybCgjaGVyb0dyYWRpZW50KSIvPjwvc3ZnPg==',\n card:\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDQwMCAzMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJjYXJkR3JhZGllbnQiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiMyYTMyM2Q7c3RvcC1vcGFjaXR5OjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiMxYzIyMmI7c3RvcC1vcGFjaXR5OjEiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgZmlsbD0idXJsKCNjYXJkR3JhZGllbnQpIi8+PC9zdmc+',\n thumbnail:\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIGZpbGw9IiMyNDJiMzUiLz48L3N2Zz4=',\n};\n","import { LRUCache } from './lruCache';\nimport { normalizeImagePath, type NormalizePathOptions } from './pathMapper';\nimport { DEFAULT_PLACEHOLDERS } from './placeholders';\nimport type {\n BlurCacheEntry,\n BlurManifestData,\n BlurManifestEntry,\n BlurPlaceholderType,\n BlurServiceMetrics,\n BlurSize,\n} from './types';\n\nexport interface BlurServiceOptions {\n cacheSize?: number;\n manifest?: BlurManifestData | Record<string, BlurManifestEntry>;\n pathOptions?: NormalizePathOptions;\n}\n\nexport class BlurService {\n private blurData: Record<string, BlurManifestEntry>;\n private readonly cache: LRUCache<string, BlurCacheEntry>;\n private readonly pathOptions?: NormalizePathOptions;\n private metadata: {\n version: string;\n generatedAt: string;\n totalImages: number;\n };\n private metrics: BlurServiceMetrics;\n\n constructor(options: BlurServiceOptions = {}) {\n this.blurData = {};\n this.pathOptions = options.pathOptions;\n this.metadata = {\n version: '2.0',\n generatedAt: new Date().toISOString(),\n totalImages: 0,\n };\n this.cache = new LRUCache(options.cacheSize ?? 500);\n this.metrics = {\n totalRequests: 0,\n cacheHits: 0,\n cacheMisses: 0,\n errors: 0,\n };\n\n if (options.manifest) {\n this.loadManifest(options.manifest);\n }\n }\n\n /**\n * Hydrate the service with a generated `blur-hashes.json` manifest or hash map.\n */\n loadManifest(\n manifest: BlurManifestData | Record<string, BlurManifestEntry>,\n ): void {\n this.cache.clear();\n\n if ('hashes' in manifest && typeof manifest.hashes === 'object' && manifest.hashes !== null) {\n const typed = manifest as BlurManifestData;\n this.blurData = { ...typed.hashes };\n this.metadata = {\n version: typed.version || '2.0',\n generatedAt: typed.generatedAt || new Date().toISOString(),\n totalImages: Object.keys(this.blurData).length,\n };\n } else {\n this.blurData = { ...(manifest as Record<string, BlurManifestEntry>) };\n this.metadata = {\n version: '2.0',\n generatedAt: new Date().toISOString(),\n totalImages: Object.keys(this.blurData).length,\n };\n }\n }\n\n /**\n * Register or update a single image's blur data at runtime.\n */\n registerEntry(imagePath: string, entry: BlurManifestEntry): void {\n this.blurData[imagePath] = entry;\n this.metadata.totalImages = Object.keys(this.blurData).length;\n this.cache.clear();\n }\n\n getDefaultPlaceholder(type: BlurPlaceholderType = 'default'): string {\n return DEFAULT_PLACEHOLDERS[type];\n }\n\n private findBlurDataByPath(imageSrc: string): BlurManifestEntry | null {\n let data = this.blurData[imageSrc];\n if (data) return data;\n\n const pathInfo = normalizeImagePath(imageSrc, this.pathOptions);\n data = this.blurData[pathInfo.normalizedPath];\n if (data) return data;\n\n const withSlash = pathInfo.normalizedPath.startsWith('/')\n ? pathInfo.normalizedPath\n : '/' + pathInfo.normalizedPath;\n const withoutSlash = pathInfo.normalizedPath.replace(/^\\/+/, '');\n\n data = this.blurData[withSlash] || this.blurData[withoutSlash];\n if (data) return data;\n\n if (pathInfo.isExternal && pathInfo.originalPath !== imageSrc) {\n data = this.blurData[pathInfo.originalPath];\n if (data) return data;\n }\n\n return null;\n }\n\n getDominantColor(imageSrc: string): string {\n const data = this.findBlurDataByPath(imageSrc);\n return data?.color || '#E5E7EB';\n }\n\n getBlurDataURL(\n imageSrc: string,\n options: {\n type?: BlurPlaceholderType;\n size?: BlurSize;\n } = {},\n ): string {\n const { type = 'default', size = 'small' } = options;\n\n this.metrics.totalRequests++;\n\n const cacheKey = `${imageSrc}-${size}`;\n if (this.cache.has(cacheKey)) {\n this.metrics.cacheHits++;\n return this.cache.get(cacheKey)!.dataUrl;\n }\n\n this.metrics.cacheMisses++;\n\n if (Object.keys(this.blurData).length === 0) {\n return this.getDefaultPlaceholder(type);\n }\n\n const data = this.findBlurDataByPath(imageSrc);\n if (!data) {\n return this.getDefaultPlaceholder(type);\n }\n\n const blurDataURL =\n data.variants?.[size] ||\n data.variants?.small ||\n this.getDefaultPlaceholder(type);\n\n this.cache.set(cacheKey, {\n dataUrl: blurDataURL,\n timestamp: Date.now(),\n });\n\n return blurDataURL;\n }\n\n getBulkBlurData(\n imageSrcs: string[],\n options: {\n type?: BlurPlaceholderType;\n size?: BlurSize;\n } = {},\n ): Record<string, string> {\n const result: Record<string, string> = {};\n for (const imageSrc of imageSrcs) {\n result[imageSrc] = this.getBlurDataURL(imageSrc, options);\n }\n return result;\n }\n\n getProgressiveData(imageSrc: string, size: BlurSize = 'small') {\n return {\n color: this.getDominantColor(imageSrc),\n blur: this.getBlurDataURL(imageSrc, { size }),\n hasBlur: this.hasBlurHash(imageSrc),\n };\n }\n\n hasBlurHash(imageSrc: string): boolean {\n return Boolean(this.findBlurDataByPath(imageSrc));\n }\n\n getMetadata() {\n const cacheHitRate =\n this.metrics.totalRequests > 0\n ? (\n (this.metrics.cacheHits / this.metrics.totalRequests) *\n 100\n ).toFixed(2)\n : '0.00';\n\n return {\n ...this.metadata,\n cacheSize: this.cache.size,\n metrics: {\n ...this.metrics,\n cacheHitRate: `${cacheHitRate}%`,\n },\n };\n }\n\n clearCache(): void {\n this.cache.clear();\n }\n\n getBlurHash(imageSrc: string): string | null {\n const data = this.findBlurDataByPath(imageSrc);\n return data?.hash || null;\n }\n\n preloadBlurData(imageSrcs: string[], size: BlurSize = 'small'): void {\n for (const imageSrc of imageSrcs) {\n this.getBlurDataURL(imageSrc, { size });\n }\n }\n\n async fetchBlurDataForImage(\n imageSrc: string,\n type: BlurPlaceholderType = 'default',\n ): Promise<string> {\n return Promise.resolve(this.getBlurDataURL(imageSrc, { type }));\n }\n\n getAvailableKeys(): string[] {\n return Object.keys(this.blurData);\n }\n\n findMatchingKeys(searchTerm: string): string[] {\n const lower = searchTerm.toLowerCase();\n return Object.keys(this.blurData).filter((key) =>\n key.toLowerCase().includes(lower),\n );\n }\n}\n\nexport function createBlurService(options?: BlurServiceOptions): BlurService {\n return new BlurService(options);\n}\n\nexport const blurService = new BlurService();\n"]}
1
+ {"version":3,"sources":["/home/runner/work/image-upload-kit/image-upload-kit/dist/blur.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,olCAAC","file":"/home/runner/work/image-upload-kit/image-upload-kit/dist/blur.cjs"}
package/dist/blur.d.cts CHANGED
@@ -1,5 +1,7 @@
1
- import { B as BlurPlaceholderType } from './blurService-DqsnfPTd.cjs';
2
- export { a as BlurCacheEntry, b as BlurData, c as BlurDataOptions, d as BlurImageSource, e as BlurManifestData, f as BlurManifestEntry, g as BlurPlaceholderStyle, h as BlurService, i as BlurServiceConfig, j as BlurServiceMetrics, k as BlurServiceOptions, l as BlurSize, D as DEFAULT_CDN_PATTERNS, N as NormalizePathOptions, P as PathInfo, m as blurService, n as createBlurService, o as createSrcSetWithBlur, p as decodeBlurHashToDataURL, q as extractImageUrls, r as getBackgroundPropsWithBlur, s as getBlurData, t as getBlurPlaceholderStyle, u as getBulkBlurData, v as getImagePropsWithBlur, w as hasBlurData, x as normalizeImagePath, y as preloadImageWithBlur } from './blurService-DqsnfPTd.cjs';
1
+ export { B as BlurPlaceholderStyle, c as createSrcSetWithBlur, d as decodeBlurHashToDataURL, e as extractImageUrls, g as getBackgroundPropsWithBlur, a as getBlurData, b as getBlurPlaceholderStyle, f as getBulkBlurData, h as getImagePropsWithBlur, i as hasBlurData, p as preloadImageWithBlur } from './blurDataUtils-DveBRtqE.cjs';
2
+ export { B as BlurService, a as BlurServiceOptions, D as DEFAULT_CDN_PATTERNS, N as NormalizePathOptions, P as PathInfo, b as blurService, c as createBlurService, n as normalizeImagePath } from './blurService-DacwylJx.cjs';
3
+ export { D as DEFAULT_PLACEHOLDERS } from './placeholders-x_3rt65M.cjs';
4
+ export { B as BlurCacheEntry, a as BlurData, b as BlurDataOptions, c as BlurImageSource, d as BlurManifestData, e as BlurManifestEntry, f as BlurPlaceholderType, g as BlurServiceConfig, h as BlurServiceMetrics, i as BlurSize } from './types-yShGNQnW.cjs';
3
5
 
4
6
  declare class LRUCache<K, V> {
5
7
  private readonly maxSize;
@@ -12,6 +14,4 @@ declare class LRUCache<K, V> {
12
14
  get size(): number;
13
15
  }
14
16
 
15
- declare const DEFAULT_PLACEHOLDERS: Record<BlurPlaceholderType, string>;
16
-
17
- export { BlurPlaceholderType, DEFAULT_PLACEHOLDERS, LRUCache };
17
+ export { LRUCache };
package/dist/blur.d.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { B as BlurPlaceholderType } from './blurService-DqsnfPTd.js';
2
- export { a as BlurCacheEntry, b as BlurData, c as BlurDataOptions, d as BlurImageSource, e as BlurManifestData, f as BlurManifestEntry, g as BlurPlaceholderStyle, h as BlurService, i as BlurServiceConfig, j as BlurServiceMetrics, k as BlurServiceOptions, l as BlurSize, D as DEFAULT_CDN_PATTERNS, N as NormalizePathOptions, P as PathInfo, m as blurService, n as createBlurService, o as createSrcSetWithBlur, p as decodeBlurHashToDataURL, q as extractImageUrls, r as getBackgroundPropsWithBlur, s as getBlurData, t as getBlurPlaceholderStyle, u as getBulkBlurData, v as getImagePropsWithBlur, w as hasBlurData, x as normalizeImagePath, y as preloadImageWithBlur } from './blurService-DqsnfPTd.js';
1
+ export { B as BlurPlaceholderStyle, c as createSrcSetWithBlur, d as decodeBlurHashToDataURL, e as extractImageUrls, g as getBackgroundPropsWithBlur, a as getBlurData, b as getBlurPlaceholderStyle, f as getBulkBlurData, h as getImagePropsWithBlur, i as hasBlurData, p as preloadImageWithBlur } from './blurDataUtils-yx9Q6HlU.js';
2
+ export { B as BlurService, a as BlurServiceOptions, D as DEFAULT_CDN_PATTERNS, N as NormalizePathOptions, P as PathInfo, b as blurService, c as createBlurService, n as normalizeImagePath } from './blurService-D5TpMNji.js';
3
+ export { D as DEFAULT_PLACEHOLDERS } from './placeholders-C4ftwaII.js';
4
+ export { B as BlurCacheEntry, a as BlurData, b as BlurDataOptions, c as BlurImageSource, d as BlurManifestData, e as BlurManifestEntry, f as BlurPlaceholderType, g as BlurServiceConfig, h as BlurServiceMetrics, i as BlurSize } from './types-yShGNQnW.js';
3
5
 
4
6
  declare class LRUCache<K, V> {
5
7
  private readonly maxSize;
@@ -12,6 +14,4 @@ declare class LRUCache<K, V> {
12
14
  get size(): number;
13
15
  }
14
16
 
15
- declare const DEFAULT_PLACEHOLDERS: Record<BlurPlaceholderType, string>;
16
-
17
- export { BlurPlaceholderType, DEFAULT_PLACEHOLDERS, LRUCache };
17
+ export { LRUCache };