img-upload-kit 1.1.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +89 -74
  2. package/MIGRATION.md +192 -0
  3. package/README.md +243 -259
  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-25GYKQ6J.js +158 -0
  17. package/dist/chunk-25GYKQ6J.js.map +1 -0
  18. package/dist/chunk-34L4TEE3.cjs +226 -0
  19. package/dist/chunk-34L4TEE3.cjs.map +1 -0
  20. package/dist/chunk-DFCSN3X7.cjs +158 -0
  21. package/dist/chunk-DFCSN3X7.cjs.map +1 -0
  22. package/dist/chunk-EWVIL57J.js +294 -0
  23. package/dist/chunk-EWVIL57J.js.map +1 -0
  24. package/dist/chunk-FP5YIWG5.cjs +135 -0
  25. package/dist/chunk-FP5YIWG5.cjs.map +1 -0
  26. package/dist/chunk-HILELQGS.js +226 -0
  27. package/dist/chunk-HILELQGS.js.map +1 -0
  28. package/dist/chunk-IDLLCVGB.js +2370 -0
  29. package/dist/chunk-IDLLCVGB.js.map +1 -0
  30. package/dist/chunk-J6A44Y3W.js +514 -0
  31. package/dist/chunk-J6A44Y3W.js.map +1 -0
  32. package/dist/chunk-LOSVFO56.cjs +145 -0
  33. package/dist/chunk-LOSVFO56.cjs.map +1 -0
  34. package/dist/chunk-MBQJ6NVJ.cjs +294 -0
  35. package/dist/chunk-MBQJ6NVJ.cjs.map +1 -0
  36. package/dist/chunk-MHGQEBPW.js +145 -0
  37. package/dist/chunk-MHGQEBPW.js.map +1 -0
  38. package/dist/chunk-QHU7FUO4.cjs +37 -0
  39. package/dist/chunk-QHU7FUO4.cjs.map +1 -0
  40. package/dist/chunk-S2IFAWJK.js +37 -0
  41. package/dist/chunk-S2IFAWJK.js.map +1 -0
  42. package/dist/chunk-TA5Y64JM.cjs +2370 -0
  43. package/dist/chunk-TA5Y64JM.cjs.map +1 -0
  44. package/dist/chunk-VYVZVUNI.js +135 -0
  45. package/dist/chunk-VYVZVUNI.js.map +1 -0
  46. package/dist/chunk-XKQMCY5Z.cjs +514 -0
  47. package/dist/chunk-XKQMCY5Z.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 +235 -220
  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
@@ -0,0 +1,158 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/types/quality.ts
2
+ var QUALITY_PRESETS = {
3
+ low: {
4
+ label: "Low",
5
+ labelAr: "\u0645\u0646\u062E\u0641\u0636\u0629",
6
+ value: 50,
7
+ description: "Smallest file \u2014 best for tiny thumbnails and icons",
8
+ descriptionAr: "\u0623\u0635\u063A\u0631 \u062D\u062C\u0645 \u2014 \u0645\u0646\u0627\u0633\u0628 \u0644\u0644\u0645\u0635\u063A\u0631\u0627\u062A \u0648\u0627\u0644\u0623\u064A\u0642\u0648\u0646\u0627\u062A \u0627\u0644\u0635\u063A\u064A\u0631\u0629",
9
+ compressionRatio: 0.12
10
+ },
11
+ medium: {
12
+ label: "Medium",
13
+ labelAr: "\u0645\u062A\u0648\u0633\u0637\u0629",
14
+ value: 72,
15
+ description: "Balanced size and quality \u2014 suitable for most web images",
16
+ descriptionAr: "\u062A\u0648\u0627\u0632\u0646 \u0628\u064A\u0646 \u0627\u0644\u062D\u062C\u0645 \u0648\u0627\u0644\u062C\u0648\u062F\u0629 \u2014 \u0645\u0646\u0627\u0633\u0628 \u0644\u0645\u0639\u0638\u0645 \u0635\u0648\u0631 \u0627\u0644\u0648\u064A\u0628",
17
+ compressionRatio: 0.22
18
+ },
19
+ high: {
20
+ label: "High",
21
+ labelAr: "\u0639\u0627\u0644\u064A\u0629",
22
+ value: 85,
23
+ description: "Recommended \u2014 sharp visuals with excellent compression",
24
+ descriptionAr: "\u0645\u0648\u0635\u0649 \u0628\u0647 \u2014 \u062C\u0648\u062F\u0629 \u0639\u0627\u0644\u064A\u0629 \u0648\u0636\u063A\u0637 \u0645\u0645\u062A\u0627\u0632",
25
+ compressionRatio: 0.3
26
+ },
27
+ maximum: {
28
+ label: "Maximum",
29
+ labelAr: "\u0623\u0642\u0635\u0649 \u062C\u0648\u062F\u0629",
30
+ value: 95,
31
+ description: "Closest to original \u2014 large file, use for hero / print",
32
+ descriptionAr: "\u0623\u0642\u0631\u0628 \u0644\u0644\u0623\u0635\u0644 \u2014 \u062D\u062C\u0645 \u0643\u0628\u064A\u0631\u060C \u0645\u0646\u0627\u0633\u0628 \u0644\u0644\u0635\u0648\u0631 \u0627\u0644\u0631\u0626\u064A\u0633\u064A\u0629 \u0648\u0627\u0644\u0637\u0628\u0627\u0639\u0629",
33
+ compressionRatio: 0.55
34
+ }
35
+ };
36
+
37
+ // src/utils/formatters.ts
38
+ function formatFileSize(bytes) {
39
+ if (bytes <= 0) return "0 Bytes";
40
+ const k = 1024;
41
+ const sizes = ["Bytes", "KB", "MB", "GB"];
42
+ const i = Math.min(
43
+ sizes.length - 1,
44
+ Math.floor(Math.log(bytes) / Math.log(k))
45
+ );
46
+ return `${Math.round(bytes / Math.pow(k, i) * 100) / 100} ${sizes[i]}`;
47
+ }
48
+ function calculateReduction(original, optimized) {
49
+ if (original <= 0) return 0;
50
+ return Math.round((original - optimized) / original * 100);
51
+ }
52
+ function estimateOutputSize(originalBytes, level) {
53
+ return Math.round(originalBytes * QUALITY_PRESETS[level].compressionRatio);
54
+ }
55
+ var creativeMessages = [
56
+ "Sprinkling digital magic \u2728",
57
+ "Painting pixels with perfection \u{1F3A8}",
58
+ "Launching to the cloud \u{1F680}",
59
+ "Creating something beautiful \u2B50",
60
+ "Transforming your vision \u26A1",
61
+ "Weaving visual excellence \u{1F4AB}",
62
+ "Crafting your masterpiece \u{1F3AD}",
63
+ "Working our magic \u{1F52E}",
64
+ "Making it pixel-perfect \u2728",
65
+ "Keep calm, creating magic \u{1F3AA}",
66
+ "Hitting the sweet spot \u{1F3AF}",
67
+ "Artist mode activated \u{1F3A8}",
68
+ "Shooting for the stars \u{1F320}",
69
+ "Compressing with love \u{1F49D}",
70
+ "Enhancing quality \u{1F48E}",
71
+ "Polishing to perfection \u2728"
72
+ ];
73
+ var creativeMessagesAr = [
74
+ "\u0646\u0636\u064A\u0641 \u0644\u0645\u0633\u0629 \u0631\u0642\u0645\u064A\u0629 \u0633\u0627\u062D\u0631\u0629 \u2728",
75
+ "\u0646\u0646\u0633\u0642 \u0627\u0644\u0628\u0643\u0633\u0644\u0627\u062A \u0628\u0625\u062A\u0642\u0627\u0646 \u{1F3A8}",
76
+ "\u0627\u0644\u0631\u0641\u0639 \u062C\u0627\u0631\u064D \u0625\u0644\u0649 \u0627\u0644\u0633\u062D\u0627\u0628\u0629 \u{1F680}",
77
+ "\u0646\u0635\u0646\u0639 \u0634\u064A\u0626\u0627\u064B \u062C\u0645\u064A\u0644\u0627\u064B \u2B50",
78
+ "\u0646\u062D\u0648\u0651\u0644 \u0631\u0624\u064A\u062A\u0643 \u0625\u0644\u0649 \u0648\u0627\u0642\u0639 \u26A1",
79
+ "\u0646\u0628\u0646\u064A \u062A\u062C\u0631\u0628\u0629 \u0628\u0635\u0631\u064A\u0629 \u0645\u0645\u064A\u0632\u0629 \u{1F4AB}",
80
+ "\u0646\u0635\u0642\u0644 \u0639\u0645\u0644\u0643 \u0628\u0627\u062D\u062A\u0631\u0627\u0641 \u{1F3AD}",
81
+ "\u0627\u0644\u0633\u062D\u0631 \u062C\u0627\u0631\u064D \u0627\u0644\u0622\u0646 \u{1F52E}",
82
+ "\u0646\u0636\u0628\u0637 \u0643\u0644 \u0628\u0643\u0633\u0644 \u0628\u0639\u0646\u0627\u064A\u0629 \u2728",
83
+ "\u0627\u0647\u062F\u0623\u060C \u0646\u062D\u0646 \u0646\u0647\u062A\u0645 \u0628\u0627\u0644\u062A\u0641\u0627\u0635\u064A\u0644 \u{1F3AA}",
84
+ "\u0646\u0642\u062A\u0631\u0628 \u0645\u0646 \u0627\u0644\u0646\u062A\u064A\u062C\u0629 \u0627\u0644\u0645\u062B\u0627\u0644\u064A\u0629 \u{1F3AF}",
85
+ "\u0648\u0636\u0639 \u0627\u0644\u0625\u0628\u062F\u0627\u0639 \u0645\u0641\u0639\u0644 \u{1F3A8}",
86
+ "\u0646\u0633\u062A\u0647\u062F\u0641 \u0623\u0641\u0636\u0644 \u0646\u062A\u064A\u062C\u0629 \u{1F320}",
87
+ "\u0636\u063A\u0637 \u0630\u0643\u064A \u0645\u0639 \u0627\u0644\u062D\u0641\u0627\u0638 \u0639\u0644\u0649 \u0627\u0644\u062C\u0648\u062F\u0629 \u{1F49D}",
88
+ "\u062A\u062D\u0633\u064A\u0646 \u0627\u0644\u062C\u0648\u062F\u0629 \u0645\u0633\u062A\u0645\u0631 \u{1F48E}",
89
+ "\u0627\u0644\u0644\u0645\u0633\u0627\u062A \u0627\u0644\u0623\u062E\u064A\u0631\u0629 \u0642\u064A\u062F \u0627\u0644\u062A\u0646\u0641\u064A\u0630 \u2728"
90
+ ];
91
+ function getStatusMessage(progress, locale = "en") {
92
+ if (progress >= 95) {
93
+ return locale === "ar" ? "\u{1F389} \u0627\u0642\u062A\u0631\u0628\u0646\u0627 \u062C\u062F\u0627\u064B..." : "\u{1F389} Almost there...";
94
+ }
95
+ if (progress >= 85) {
96
+ return locale === "ar" ? "\u2728 \u0646\u0636\u0639 \u0627\u0644\u0644\u0645\u0633\u0627\u062A \u0627\u0644\u0623\u062E\u064A\u0631\u0629..." : "\u2728 Polishing the final details...";
97
+ }
98
+ const list = locale === "ar" ? creativeMessagesAr : creativeMessages;
99
+ const clampedProgress = Math.max(0, Math.min(99, progress));
100
+ const messageIndex = Math.min(
101
+ list.length - 1,
102
+ Math.floor(clampedProgress / 100 * list.length)
103
+ );
104
+ return list[messageIndex];
105
+ }
106
+ function createSuccessMessage(originalSize, optimizedSize, compact = false, locale = "en") {
107
+ const reduction = calculateReduction(originalSize, optimizedSize);
108
+ const original = formatFileSize(originalSize);
109
+ const optimized = formatFileSize(optimizedSize);
110
+ if (compact) {
111
+ if (reduction > 50) {
112
+ return locale === "ar" ? `\u{1F389} \u0623\u0635\u063A\u0631 \u0628\u0646\u0633\u0628\u0629 ${reduction}%! (${original} \u2192 ${optimized})` : `\u{1F389} ${reduction}% smaller! (${original} \u2192 ${optimized})`;
113
+ }
114
+ if (reduction > 0) {
115
+ return locale === "ar" ? `\u2713 \u0623\u0635\u063A\u0631 \u0628\u0646\u0633\u0628\u0629 ${reduction}% (${original} \u2192 ${optimized})` : `\u2713 ${reduction}% smaller (${original} \u2192 ${optimized})`;
116
+ }
117
+ return `\u2713 ${optimized}`;
118
+ }
119
+ if (reduction > 70) {
120
+ return locale === "ar" ? `\u{1F389} \u0631\u0627\u0626\u0639! \u062A\u0645 \u062A\u0642\u0644\u064A\u0644 \u0627\u0644\u062D\u062C\u0645 \u0628\u0646\u0633\u0628\u0629 ${reduction}% (${original} \u2192 ${optimized})` : `\u{1F389} Amazing! Reduced by ${reduction}% (${original} \u2192 ${optimized})`;
121
+ }
122
+ if (reduction > 50) {
123
+ return locale === "ar" ? `\u2728 \u0645\u0645\u062A\u0627\u0632! \u062A\u0645 \u062A\u0642\u0644\u064A\u0644 \u0627\u0644\u062D\u062C\u0645 \u0628\u0646\u0633\u0628\u0629 ${reduction}% (${original} \u2192 ${optimized})` : `\u2728 Great! Reduced by ${reduction}% (${original} \u2192 ${optimized})`;
124
+ }
125
+ if (reduction > 20) {
126
+ return locale === "ar" ? `\u2713 \u0627\u0643\u062A\u0645\u0644 \u0627\u0644\u0631\u0641\u0639! \u062A\u0645 \u062A\u0642\u0644\u064A\u0644 \u0627\u0644\u062D\u062C\u0645 \u0628\u0646\u0633\u0628\u0629 ${reduction}% (${original} \u2192 ${optimized})` : `\u2713 Upload complete! Reduced by ${reduction}% (${original} \u2192 ${optimized})`;
127
+ }
128
+ return locale === "ar" ? `\u2713 \u0627\u0643\u062A\u0645\u0644 \u0627\u0644\u0631\u0641\u0639! (${original} \u2192 ${optimized})` : `\u2713 Upload complete! (${original} \u2192 ${optimized})`;
129
+ }
130
+ var FILE_TYPE_ERROR_REGEX = /\b(?:file\s+type|mime\s+type|invalid\s+type|unsupported|format|mime)\b/i;
131
+ function getFriendlyErrorMessage(error, locale = "en") {
132
+ const lower = error.toLowerCase();
133
+ if (lower.includes("size") || lower.includes("large") || lower.includes("exceeds")) {
134
+ return locale === "ar" ? "\u0627\u0644\u0645\u0644\u0641 \u0643\u0628\u064A\u0631 \u062C\u062F\u0627\u064B. \u064A\u0631\u062C\u0649 \u0627\u062E\u062A\u064A\u0627\u0631 \u0635\u0648\u0631\u0629 \u0623\u0635\u063A\u0631." : "File is too large. Please choose a smaller image.";
135
+ }
136
+ if (lower.includes("network") || lower.includes("fetch") || lower.includes("connection")) {
137
+ return locale === "ar" ? "\u062D\u062F\u062B \u062E\u0637\u0623 \u0641\u064A \u0627\u0644\u0634\u0628\u0643\u0629. \u064A\u0631\u062C\u0649 \u0627\u0644\u062A\u062D\u0642\u0642 \u0645\u0646 \u0627\u0644\u0627\u062A\u0635\u0627\u0644 \u0648\u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649." : "Network error. Please check your connection and try again.";
138
+ }
139
+ if (lower.includes("timeout") || lower.includes("timed out")) {
140
+ return locale === "ar" ? "\u0627\u0646\u062A\u0647\u062A \u0645\u0647\u0644\u0629 \u0627\u0644\u0631\u0641\u0639. \u064A\u0631\u062C\u0649 \u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649." : "Upload timed out. Please try again.";
141
+ }
142
+ if (FILE_TYPE_ERROR_REGEX.test(error)) {
143
+ return locale === "ar" ? "\u0646\u0648\u0639 \u0627\u0644\u0645\u0644\u0641 \u063A\u064A\u0631 \u0635\u0627\u0644\u062D. \u064A\u0631\u062C\u0649 \u0631\u0641\u0639 \u0635\u0648\u0631\u0629 \u0635\u0627\u0644\u062D\u0629 (JPEG, PNG, WebP, AVIF)." : "Invalid file type. Please upload a valid image (JPEG, PNG, WebP, AVIF).";
144
+ }
145
+ if (error) return error;
146
+ return locale === "ar" ? "\u0641\u0634\u0644 \u0627\u0644\u0631\u0641\u0639. \u064A\u0631\u062C\u0649 \u0627\u0644\u0645\u062D\u0627\u0648\u0644\u0629 \u0645\u0631\u0629 \u0623\u062E\u0631\u0649." : "Upload failed. Please try again.";
147
+ }
148
+
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+ exports.QUALITY_PRESETS = QUALITY_PRESETS; exports.formatFileSize = formatFileSize; exports.calculateReduction = calculateReduction; exports.estimateOutputSize = estimateOutputSize; exports.getStatusMessage = getStatusMessage; exports.createSuccessMessage = createSuccessMessage; exports.getFriendlyErrorMessage = getFriendlyErrorMessage;
158
+ //# sourceMappingURL=chunk-DFCSN3X7.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["e:\\Personal-Projects\\image-upload-kit\\dist\\chunk-DFCSN3X7.cjs"],"names":[],"mappings":"AAAA;AACA,IAAI,gBAAgB,EAAE;AACtB,EAAE,GAAG,EAAE;AACP,IAAI,KAAK,EAAE,KAAK;AAChB,IAAI,OAAO,EAAE,sCAAsC;AACnD,IAAI,KAAK,EAAE,EAAE;AACb,IAAI,WAAW,EAAE,yDAAyD;AAC1E,IAAI,aAAa,EAAE,4OAA4O;AAC/P,IAAI,gBAAgB,EAAE;AACtB,EAAE,CAAC;AACH,EAAE,MAAM,EAAE;AACV,IAAI,KAAK,EAAE,QAAQ;AACnB,IAAI,OAAO,EAAE,sCAAsC;AACnD,IAAI,KAAK,EAAE,EAAE;AACb,IAAI,WAAW,EAAE,+DAA+D;AAChF,IAAI,aAAa,EAAE,oPAAoP;AACvQ,IAAI,gBAAgB,EAAE;AACtB,EAAE,CAAC;AACH,EAAE,IAAI,EAAE;AACR,IAAI,KAAK,EAAE,MAAM;AACjB,IAAI,OAAO,EAAE,gCAAgC;AAC7C,IAAI,KAAK,EAAE,EAAE;AACb,IAAI,WAAW,EAAE,6DAA6D;AAC9E,IAAI,aAAa,EAAE,8JAA8J;AACjL,IAAI,gBAAgB,EAAE;AACtB,EAAE,CAAC;AACH,EAAE,OAAO,EAAE;AACX,IAAI,KAAK,EAAE,SAAS;AACpB,IAAI,OAAO,EAAE,mDAAmD;AAChE,IAAI,KAAK,EAAE,EAAE;AACb,IAAI,WAAW,EAAE,6DAA6D;AAC9E,IAAI,aAAa,EAAE,kRAAkR;AACrS,IAAI,gBAAgB,EAAE;AACtB,EAAE;AACF,CAAC;AACD;AACA;AACA,SAAS,cAAc,CAAC,KAAK,EAAE;AAC/B,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,OAAO,SAAS;AAClC,EAAE,MAAM,EAAE,EAAE,IAAI;AAChB,EAAE,MAAM,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;AAC3C,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,GAAG;AACpB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;AACpB,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5C,EAAE,CAAC;AACH,EAAE,OAAO,CAAC,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,MAAA;AACA,IAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,IAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"E:\\Personal-Projects\\image-upload-kit\\dist\\chunk-DFCSN3X7.cjs","sourcesContent":[null]}
@@ -0,0 +1,294 @@
1
+ // src/blur/lruCache.ts
2
+ var LRUCache = class {
3
+ maxSize;
4
+ cache;
5
+ constructor(maxSize = 500) {
6
+ this.maxSize = Math.max(1, maxSize);
7
+ this.cache = /* @__PURE__ */ new Map();
8
+ }
9
+ get(key) {
10
+ if (!this.cache.has(key)) return void 0;
11
+ const value = this.cache.get(key);
12
+ this.cache.delete(key);
13
+ this.cache.set(key, value);
14
+ return value;
15
+ }
16
+ set(key, value) {
17
+ if (this.cache.has(key)) {
18
+ this.cache.delete(key);
19
+ }
20
+ if (this.cache.size >= this.maxSize) {
21
+ const firstKey = this.cache.keys().next().value;
22
+ if (firstKey !== void 0) {
23
+ this.cache.delete(firstKey);
24
+ }
25
+ }
26
+ this.cache.set(key, value);
27
+ }
28
+ has(key) {
29
+ return this.cache.has(key);
30
+ }
31
+ clear() {
32
+ this.cache.clear();
33
+ }
34
+ get size() {
35
+ return this.cache.size;
36
+ }
37
+ };
38
+
39
+ // src/blur/pathMapper.ts
40
+ var DEFAULT_CDN_PATTERNS = [
41
+ /^https?:\/\/[^/]+\.supabase\.co\/storage\/v1\/object\/public\/([^/]+)\/(.+)$/,
42
+ /^https?:\/\/[^/]+\.r2\.dev\/(.+)$/,
43
+ /^https?:\/\/[^/]+\.amazonaws\.com\/(.+)$/,
44
+ /^https?:\/\/[^/]+\.cloudflare\.com\/(.+)$/,
45
+ /^https?:\/\/cdn\.[^/]+\/(.+)$/
46
+ ];
47
+ function normalizeImagePath(imageSrc, options = {}) {
48
+ const originalPath = imageSrc;
49
+ let normalizedPath = imageSrc;
50
+ let isExternal = false;
51
+ try {
52
+ if (imageSrc.startsWith("data:") || imageSrc.startsWith("blob:")) {
53
+ return {
54
+ normalizedPath: imageSrc,
55
+ isExternal: false,
56
+ originalPath
57
+ };
58
+ }
59
+ const patterns = options.cdnPatterns || DEFAULT_CDN_PATTERNS;
60
+ if (imageSrc.startsWith("http://") || imageSrc.startsWith("https://")) {
61
+ const url = new URL(imageSrc);
62
+ isExternal = true;
63
+ const cleanUrlNoQuery = `${url.origin}${url.pathname}`;
64
+ for (const pattern of patterns) {
65
+ const match = cleanUrlNoQuery.match(pattern);
66
+ if (match) {
67
+ const groups = match.slice(1).filter(Boolean);
68
+ const pathPart = groups.join("/");
69
+ normalizedPath = "/" + pathPart.replace(/^\/+/, "");
70
+ break;
71
+ }
72
+ }
73
+ if (normalizedPath === imageSrc) {
74
+ normalizedPath = url.pathname;
75
+ }
76
+ } else {
77
+ normalizedPath = normalizedPath.split("?")[0].split("#")[0];
78
+ }
79
+ normalizedPath = normalizedPath.replace(/\\/g, "/").replace(/^\.\.?\//g, "");
80
+ if (!normalizedPath.startsWith("/")) {
81
+ normalizedPath = "/" + normalizedPath;
82
+ }
83
+ const prefixesToStrip = options.stripPrefixes || ["/public/"];
84
+ for (const prefix of prefixesToStrip) {
85
+ if (normalizedPath.startsWith(prefix)) {
86
+ normalizedPath = "/" + normalizedPath.slice(prefix.length).replace(/^\/+/, "");
87
+ }
88
+ }
89
+ const segments = normalizedPath.split("/").filter(Boolean);
90
+ const filename = segments[segments.length - 1];
91
+ const folder = segments.length > 1 ? segments.slice(0, -1).join("/") : void 0;
92
+ const dotIdx = filename ? filename.lastIndexOf(".") : -1;
93
+ const extension = filename && dotIdx > 0 ? filename.slice(dotIdx + 1).toLowerCase() : void 0;
94
+ return {
95
+ normalizedPath,
96
+ folder,
97
+ filename,
98
+ extension,
99
+ isExternal,
100
+ originalPath
101
+ };
102
+ } catch {
103
+ return {
104
+ normalizedPath: imageSrc,
105
+ isExternal: false,
106
+ originalPath
107
+ };
108
+ }
109
+ }
110
+
111
+ // src/blur/placeholders.ts
112
+ var DEFAULT_PLACEHOLDERS = {
113
+ default: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTUwIiBoZWlnaHQ9IjE1MCIgdmlld0JveD0iMCAwIDE1MCAxNTAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkaWVudCIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIwJSIgc3R5bGU9InN0b3AtY29sb3I6IzJhMzIzZDtzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iNTAlIiBzdHlsZT0ic3RvcC1jb2xvcjojMjEyNzMwO3N0b3Atb3BhY2l0eToxIi8+PHN0b3Agb2Zmc2V0PSIxMDAlIiBzdHlsZT0ic3RvcC1jb2xvcjojMTgxZDI0O3N0b3Atb3BhY2l0eToxIi8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3Qgd2lkdGg9IjE1MCIgaGVpZ2h0PSIxNTAiIGZpbGw9InVybCgjZ3JhZGllbnQpIi8+PC9zdmc+",
114
+ hero: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTkyMCIgaGVpZ2h0PSIxMDgwIiB2aWV3Qm94PSIwIDAgMTkyMCAxMDgwIiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzPjxsaW5lYXJHcmFkaWVudCBpZD0iaGVyb0dyYWRpZW50IiB4MT0iMCUiIHkxPSIwJSIgeDI9IjEwMCUiIHkyPSIxMDAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdHlsZT0ic3RvcC1jb2xvcjojMmQzNzQ4O3N0b3Atb3BhY2l0eToxIi8+PHN0b3Agb2Zmc2V0PSIzMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiMyMzJiMzg7c3RvcC1vcGFjaXR5OjEiLz48c3RvcCBvZmZzZXQ9IjcwJSIgc3R5bGU9InN0b3AtY29sb3I6IzFlMjUzMDtzdG9wLW9wYWNpdHk6MSIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3R5bGU9InN0b3AtY29sb3I6IzE3MWQyNztzdG9wLW9wYWNpdHk6MSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHdpZHRoPSIxOTIwIiBoZWlnaHQ9IjEwODAiIGZpbGw9InVybCgjaGVyb0dyYWRpZW50KSIvPjwvc3ZnPg==",
115
+ card: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDQwMCAzMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJjYXJkR3JhZGllbnQiIHgxPSIwJSIgeTE9IjAlIiB4Mj0iMTAwJSIgeTI9IjEwMCUiPjxzdG9wIG9mZnNldD0iMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiMyYTMyM2Q7c3RvcC1vcGFjaXR5OjEiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0eWxlPSJzdG9wLWNvbG9yOiMxYzIyMmI7c3RvcC1vcGFjaXR5OjEiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cmVjdCB3aWR0aD0iNDAwIiBoZWlnaHQ9IjMwMCIgZmlsbD0idXJsKCNjYXJkR3JhZGllbnQpIi8+PC9zdmc+",
116
+ thumbnail: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9IjEwMCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHJlY3Qgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIGZpbGw9IiMyNDJiMzUiLz48L3N2Zz4="
117
+ };
118
+
119
+ // src/blur/blurService.ts
120
+ var BlurService = class {
121
+ blurData;
122
+ cache;
123
+ pathOptions;
124
+ metadata;
125
+ metrics;
126
+ constructor(options = {}) {
127
+ this.blurData = {};
128
+ this.pathOptions = options.pathOptions;
129
+ this.metadata = {
130
+ version: "2.0",
131
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
132
+ totalImages: 0
133
+ };
134
+ this.cache = new LRUCache(options.cacheSize ?? 500);
135
+ this.metrics = {
136
+ totalRequests: 0,
137
+ cacheHits: 0,
138
+ cacheMisses: 0,
139
+ errors: 0
140
+ };
141
+ if (options.manifest) {
142
+ this.loadManifest(options.manifest);
143
+ }
144
+ }
145
+ /**
146
+ * Hydrate the service with a generated `blur-hashes.json` manifest or hash map.
147
+ */
148
+ loadManifest(manifest) {
149
+ this.cache.clear();
150
+ if ("hashes" in manifest && typeof manifest.hashes === "object" && manifest.hashes !== null) {
151
+ const typed = manifest;
152
+ this.blurData = { ...typed.hashes };
153
+ this.metadata = {
154
+ version: typed.version || "2.0",
155
+ generatedAt: typed.generatedAt || (/* @__PURE__ */ new Date()).toISOString(),
156
+ totalImages: Object.keys(this.blurData).length
157
+ };
158
+ } else {
159
+ this.blurData = { ...manifest };
160
+ this.metadata = {
161
+ version: "2.0",
162
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
163
+ totalImages: Object.keys(this.blurData).length
164
+ };
165
+ }
166
+ }
167
+ /**
168
+ * Register or update a single image's blur data at runtime.
169
+ */
170
+ registerEntry(imagePath, entry) {
171
+ this.blurData[imagePath] = entry;
172
+ this.metadata.totalImages = Object.keys(this.blurData).length;
173
+ this.cache.clear();
174
+ }
175
+ getDefaultPlaceholder(type = "default") {
176
+ return DEFAULT_PLACEHOLDERS[type];
177
+ }
178
+ findBlurDataByPath(imageSrc) {
179
+ let data = this.blurData[imageSrc];
180
+ if (data) return data;
181
+ const pathInfo = normalizeImagePath(imageSrc, this.pathOptions);
182
+ data = this.blurData[pathInfo.normalizedPath];
183
+ if (data) return data;
184
+ const withSlash = pathInfo.normalizedPath.startsWith("/") ? pathInfo.normalizedPath : "/" + pathInfo.normalizedPath;
185
+ const withoutSlash = pathInfo.normalizedPath.replace(/^\/+/, "");
186
+ data = this.blurData[withSlash] || this.blurData[withoutSlash];
187
+ if (data) return data;
188
+ const firstSlashIdx = withoutSlash.indexOf("/");
189
+ if (firstSlashIdx > 0 && firstSlashIdx < withoutSlash.length - 1) {
190
+ const withoutBucket = withoutSlash.slice(firstSlashIdx + 1);
191
+ data = this.blurData["/" + withoutBucket] || this.blurData[withoutBucket];
192
+ if (data) return data;
193
+ }
194
+ if (pathInfo.isExternal && pathInfo.originalPath !== imageSrc) {
195
+ data = this.blurData[pathInfo.originalPath];
196
+ if (data) return data;
197
+ }
198
+ return null;
199
+ }
200
+ getDominantColor(imageSrc) {
201
+ const data = this.findBlurDataByPath(imageSrc);
202
+ return data?.color || "#E5E7EB";
203
+ }
204
+ getBlurDataURL(imageSrc, options = {}) {
205
+ const { type = "default", size = "small" } = options;
206
+ this.metrics.totalRequests++;
207
+ const cacheKey = `${imageSrc}-${size}-${type}`;
208
+ if (this.cache.has(cacheKey)) {
209
+ this.metrics.cacheHits++;
210
+ return this.cache.get(cacheKey).dataUrl;
211
+ }
212
+ this.metrics.cacheMisses++;
213
+ if (Object.keys(this.blurData).length === 0) {
214
+ return this.getDefaultPlaceholder(type);
215
+ }
216
+ const data = this.findBlurDataByPath(imageSrc);
217
+ if (!data) {
218
+ return this.getDefaultPlaceholder(type);
219
+ }
220
+ const blurDataURL = data.variants?.[size] || data.variants?.small || this.getDefaultPlaceholder(type);
221
+ this.cache.set(cacheKey, {
222
+ dataUrl: blurDataURL,
223
+ timestamp: Date.now()
224
+ });
225
+ return blurDataURL;
226
+ }
227
+ getBulkBlurData(imageSrcs, options = {}) {
228
+ const result = {};
229
+ for (const imageSrc of imageSrcs) {
230
+ result[imageSrc] = this.getBlurDataURL(imageSrc, options);
231
+ }
232
+ return result;
233
+ }
234
+ getProgressiveData(imageSrc, size = "small") {
235
+ return {
236
+ color: this.getDominantColor(imageSrc),
237
+ blur: this.getBlurDataURL(imageSrc, { size }),
238
+ hasBlur: this.hasBlurHash(imageSrc)
239
+ };
240
+ }
241
+ hasBlurHash(imageSrc) {
242
+ return Boolean(this.findBlurDataByPath(imageSrc));
243
+ }
244
+ getMetadata() {
245
+ const cacheHitRate = this.metrics.totalRequests > 0 ? (this.metrics.cacheHits / this.metrics.totalRequests * 100).toFixed(2) : "0.00";
246
+ return {
247
+ ...this.metadata,
248
+ cacheSize: this.cache.size,
249
+ metrics: {
250
+ ...this.metrics,
251
+ cacheHitRate: `${cacheHitRate}%`
252
+ }
253
+ };
254
+ }
255
+ clearCache() {
256
+ this.cache.clear();
257
+ }
258
+ getBlurHash(imageSrc) {
259
+ const data = this.findBlurDataByPath(imageSrc);
260
+ return data?.hash || null;
261
+ }
262
+ preloadBlurData(imageSrcs, size = "small") {
263
+ for (const imageSrc of imageSrcs) {
264
+ this.getBlurDataURL(imageSrc, { size });
265
+ }
266
+ }
267
+ async fetchBlurDataForImage(imageSrc, type = "default") {
268
+ return Promise.resolve(this.getBlurDataURL(imageSrc, { type }));
269
+ }
270
+ getAvailableKeys() {
271
+ return Object.keys(this.blurData);
272
+ }
273
+ findMatchingKeys(searchTerm) {
274
+ const lower = searchTerm.toLowerCase();
275
+ return Object.keys(this.blurData).filter(
276
+ (key) => key.toLowerCase().includes(lower)
277
+ );
278
+ }
279
+ };
280
+ function createBlurService(options) {
281
+ return new BlurService(options);
282
+ }
283
+ var blurService = new BlurService();
284
+
285
+ export {
286
+ LRUCache,
287
+ DEFAULT_CDN_PATTERNS,
288
+ normalizeImagePath,
289
+ DEFAULT_PLACEHOLDERS,
290
+ BlurService,
291
+ createBlurService,
292
+ blurService
293
+ };
294
+ //# sourceMappingURL=chunk-EWVIL57J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/blur/lruCache.ts","../src/blur/pathMapper.ts","../src/blur/placeholders.ts","../src/blur/blurService.ts"],"sourcesContent":["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[] = [\r\n /^https?:\\/\\/[^/]+\\.supabase\\.co\\/storage\\/v1\\/object\\/public\\/([^/]+)\\/(.+)$/,\r\n /^https?:\\/\\/[^/]+\\.r2\\.dev\\/(.+)$/,\r\n /^https?:\\/\\/[^/]+\\.amazonaws\\.com\\/(.+)$/,\r\n /^https?:\\/\\/[^/]+\\.cloudflare\\.com\\/(.+)$/,\r\n /^https?:\\/\\/cdn\\.[^/]+\\/(.+)$/,\r\n];\r\n\r\nexport interface NormalizePathOptions {\r\n cdnPatterns?: RegExp[];\r\n stripPrefixes?: string[];\r\n}\r\n\r\nexport interface PathInfo {\r\n normalizedPath: string;\r\n folder?: string;\r\n filename?: string;\r\n extension?: string;\r\n isExternal: boolean;\r\n originalPath: string;\r\n}\r\n\r\n/**\r\n * Project-agnostic image URL / path normalizer.\r\n * Strips query parameters, leading `/public/`, relative `./`, and common CDN prefixes\r\n * so manifest keys match consistently across local and CDN environments.\r\n */\r\nexport function normalizeImagePath(\r\n imageSrc: string,\r\n options: NormalizePathOptions = {},\r\n): PathInfo {\r\n const originalPath = imageSrc;\r\n let normalizedPath = imageSrc;\r\n let isExternal = false;\r\n\r\n try {\r\n if (imageSrc.startsWith('data:') || imageSrc.startsWith('blob:')) {\r\n return {\r\n normalizedPath: imageSrc,\r\n isExternal: false,\r\n originalPath,\r\n };\r\n }\r\n\r\n const patterns = options.cdnPatterns || DEFAULT_CDN_PATTERNS;\r\n\r\n if (imageSrc.startsWith('http://') || imageSrc.startsWith('https://')) {\r\n const url = new URL(imageSrc);\r\n isExternal = true;\r\n const cleanUrlNoQuery = `${url.origin}${url.pathname}`;\r\n\r\n for (const pattern of patterns) {\r\n const match = cleanUrlNoQuery.match(pattern);\r\n if (match) {\r\n const groups = match.slice(1).filter(Boolean);\r\n const pathPart = groups.join('/');\r\n normalizedPath = '/' + pathPart.replace(/^\\/+/, '');\r\n break;\r\n }\r\n }\r\n\r\n if (normalizedPath === imageSrc) {\r\n normalizedPath = url.pathname;\r\n }\r\n } else {\r\n normalizedPath = normalizedPath.split('?')[0].split('#')[0];\r\n }\r\n\r\n normalizedPath = normalizedPath.replace(/\\\\/g, '/').replace(/^\\.\\.?\\//g, '');\r\n\r\n if (!normalizedPath.startsWith('/')) {\r\n normalizedPath = '/' + normalizedPath;\r\n }\r\n\r\n const prefixesToStrip = options.stripPrefixes || ['/public/'];\r\n for (const prefix of prefixesToStrip) {\r\n if (normalizedPath.startsWith(prefix)) {\r\n normalizedPath = '/' + normalizedPath.slice(prefix.length).replace(/^\\/+/, '');\r\n }\r\n }\r\n\r\n const segments = normalizedPath.split('/').filter(Boolean);\r\n const filename = segments[segments.length - 1];\r\n const folder =\r\n segments.length > 1 ? segments.slice(0, -1).join('/') : undefined;\r\n const dotIdx = filename ? filename.lastIndexOf('.') : -1;\r\n const extension =\r\n filename && dotIdx > 0 ? filename.slice(dotIdx + 1).toLowerCase() : undefined;\r\n\r\n return {\r\n normalizedPath,\r\n folder,\r\n filename,\r\n extension,\r\n isExternal,\r\n originalPath,\r\n };\r\n } catch {\r\n return {\r\n normalizedPath: imageSrc,\r\n isExternal: false,\r\n originalPath,\r\n };\r\n }\r\n}\r\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';\r\nimport { normalizeImagePath, type NormalizePathOptions } from './pathMapper';\r\nimport { DEFAULT_PLACEHOLDERS } from './placeholders';\r\nimport type {\r\n BlurCacheEntry,\r\n BlurManifestData,\r\n BlurManifestEntry,\r\n BlurPlaceholderType,\r\n BlurServiceMetrics,\r\n BlurSize,\r\n} from './types';\r\n\r\nexport interface BlurServiceOptions {\r\n cacheSize?: number;\r\n manifest?: BlurManifestData | Record<string, BlurManifestEntry>;\r\n pathOptions?: NormalizePathOptions;\r\n}\r\n\r\nexport class BlurService {\r\n private blurData: Record<string, BlurManifestEntry>;\r\n private readonly cache: LRUCache<string, BlurCacheEntry>;\r\n private readonly pathOptions?: NormalizePathOptions;\r\n private metadata: {\r\n version: string;\r\n generatedAt: string;\r\n totalImages: number;\r\n };\r\n private metrics: BlurServiceMetrics;\r\n\r\n constructor(options: BlurServiceOptions = {}) {\r\n this.blurData = {};\r\n this.pathOptions = options.pathOptions;\r\n this.metadata = {\r\n version: '2.0',\r\n generatedAt: new Date().toISOString(),\r\n totalImages: 0,\r\n };\r\n this.cache = new LRUCache(options.cacheSize ?? 500);\r\n this.metrics = {\r\n totalRequests: 0,\r\n cacheHits: 0,\r\n cacheMisses: 0,\r\n errors: 0,\r\n };\r\n\r\n if (options.manifest) {\r\n this.loadManifest(options.manifest);\r\n }\r\n }\r\n\r\n /**\r\n * Hydrate the service with a generated `blur-hashes.json` manifest or hash map.\r\n */\r\n loadManifest(\r\n manifest: BlurManifestData | Record<string, BlurManifestEntry>,\r\n ): void {\r\n this.cache.clear();\r\n\r\n if ('hashes' in manifest && typeof manifest.hashes === 'object' && manifest.hashes !== null) {\r\n const typed = manifest as BlurManifestData;\r\n this.blurData = { ...typed.hashes };\r\n this.metadata = {\r\n version: typed.version || '2.0',\r\n generatedAt: typed.generatedAt || new Date().toISOString(),\r\n totalImages: Object.keys(this.blurData).length,\r\n };\r\n } else {\r\n this.blurData = { ...(manifest as Record<string, BlurManifestEntry>) };\r\n this.metadata = {\r\n version: '2.0',\r\n generatedAt: new Date().toISOString(),\r\n totalImages: Object.keys(this.blurData).length,\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Register or update a single image's blur data at runtime.\r\n */\r\n registerEntry(imagePath: string, entry: BlurManifestEntry): void {\r\n this.blurData[imagePath] = entry;\r\n this.metadata.totalImages = Object.keys(this.blurData).length;\r\n this.cache.clear();\r\n }\r\n\r\n getDefaultPlaceholder(type: BlurPlaceholderType = 'default'): string {\r\n return DEFAULT_PLACEHOLDERS[type];\r\n }\r\n\r\n private findBlurDataByPath(imageSrc: string): BlurManifestEntry | null {\r\n let data = this.blurData[imageSrc];\r\n if (data) return data;\r\n\r\n const pathInfo = normalizeImagePath(imageSrc, this.pathOptions);\r\n data = this.blurData[pathInfo.normalizedPath];\r\n if (data) return data;\r\n\r\n const withSlash = pathInfo.normalizedPath.startsWith('/')\r\n ? pathInfo.normalizedPath\r\n : '/' + pathInfo.normalizedPath;\r\n const withoutSlash = pathInfo.normalizedPath.replace(/^\\/+/, '');\r\n\r\n data = this.blurData[withSlash] || this.blurData[withoutSlash];\r\n if (data) return data;\r\n\r\n const firstSlashIdx = withoutSlash.indexOf('/');\r\n if (firstSlashIdx > 0 && firstSlashIdx < withoutSlash.length - 1) {\r\n const withoutBucket = withoutSlash.slice(firstSlashIdx + 1);\r\n data =\r\n this.blurData['/' + withoutBucket] || this.blurData[withoutBucket];\r\n if (data) return data;\r\n }\r\n\r\n if (pathInfo.isExternal && pathInfo.originalPath !== imageSrc) {\r\n data = this.blurData[pathInfo.originalPath];\r\n if (data) return data;\r\n }\r\n\r\n return null;\r\n }\r\n\r\n getDominantColor(imageSrc: string): string {\r\n const data = this.findBlurDataByPath(imageSrc);\r\n return data?.color || '#E5E7EB';\r\n }\r\n\r\n getBlurDataURL(\r\n imageSrc: string,\r\n options: {\r\n type?: BlurPlaceholderType;\r\n size?: BlurSize;\r\n } = {},\r\n ): string {\r\n const { type = 'default', size = 'small' } = options;\r\n\r\n this.metrics.totalRequests++;\r\n\r\n const cacheKey = `${imageSrc}-${size}-${type}`;\r\n if (this.cache.has(cacheKey)) {\r\n this.metrics.cacheHits++;\r\n return this.cache.get(cacheKey)!.dataUrl;\r\n }\r\n\r\n this.metrics.cacheMisses++;\r\n\r\n if (Object.keys(this.blurData).length === 0) {\r\n return this.getDefaultPlaceholder(type);\r\n }\r\n\r\n const data = this.findBlurDataByPath(imageSrc);\r\n if (!data) {\r\n return this.getDefaultPlaceholder(type);\r\n }\r\n\r\n const blurDataURL =\r\n data.variants?.[size] ||\r\n data.variants?.small ||\r\n this.getDefaultPlaceholder(type);\r\n\r\n this.cache.set(cacheKey, {\r\n dataUrl: blurDataURL,\r\n timestamp: Date.now(),\r\n });\r\n\r\n return blurDataURL;\r\n }\r\n\r\n getBulkBlurData(\r\n imageSrcs: string[],\r\n options: {\r\n type?: BlurPlaceholderType;\r\n size?: BlurSize;\r\n } = {},\r\n ): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n for (const imageSrc of imageSrcs) {\r\n result[imageSrc] = this.getBlurDataURL(imageSrc, options);\r\n }\r\n return result;\r\n }\r\n\r\n getProgressiveData(imageSrc: string, size: BlurSize = 'small') {\r\n return {\r\n color: this.getDominantColor(imageSrc),\r\n blur: this.getBlurDataURL(imageSrc, { size }),\r\n hasBlur: this.hasBlurHash(imageSrc),\r\n };\r\n }\r\n\r\n hasBlurHash(imageSrc: string): boolean {\r\n return Boolean(this.findBlurDataByPath(imageSrc));\r\n }\r\n\r\n getMetadata() {\r\n const cacheHitRate =\r\n this.metrics.totalRequests > 0\r\n ? (\r\n (this.metrics.cacheHits / this.metrics.totalRequests) *\r\n 100\r\n ).toFixed(2)\r\n : '0.00';\r\n\r\n return {\r\n ...this.metadata,\r\n cacheSize: this.cache.size,\r\n metrics: {\r\n ...this.metrics,\r\n cacheHitRate: `${cacheHitRate}%`,\r\n },\r\n };\r\n }\r\n\r\n clearCache(): void {\r\n this.cache.clear();\r\n }\r\n\r\n getBlurHash(imageSrc: string): string | null {\r\n const data = this.findBlurDataByPath(imageSrc);\r\n return data?.hash || null;\r\n }\r\n\r\n preloadBlurData(imageSrcs: string[], size: BlurSize = 'small'): void {\r\n for (const imageSrc of imageSrcs) {\r\n this.getBlurDataURL(imageSrc, { size });\r\n }\r\n }\r\n\r\n async fetchBlurDataForImage(\r\n imageSrc: string,\r\n type: BlurPlaceholderType = 'default',\r\n ): Promise<string> {\r\n return Promise.resolve(this.getBlurDataURL(imageSrc, { type }));\r\n }\r\n\r\n getAvailableKeys(): string[] {\r\n return Object.keys(this.blurData);\r\n }\r\n\r\n findMatchingKeys(searchTerm: string): string[] {\r\n const lower = searchTerm.toLowerCase();\r\n return Object.keys(this.blurData).filter((key) =>\r\n key.toLowerCase().includes(lower),\r\n );\r\n }\r\n}\r\n\r\nexport function createBlurService(options?: BlurServiceOptions): BlurService {\r\n return new BlurService(options);\r\n}\r\n\r\nexport const blurService = new BlurService();\r\n"],"mappings":"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","names":[]}
@@ -0,0 +1,135 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/blur/blurDataUtils.ts
2
+ var _blurhash = require('blurhash');
3
+ function formatCssUrl(rawUrl) {
4
+ const escaped = rawUrl.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/[\r\n]/g, "");
5
+ return `url("${escaped}")`;
6
+ }
7
+ function getBlurData(image) {
8
+ if (!image) {
9
+ return {
10
+ blurDataUrl: "",
11
+ blurColor: "#E5E7EB",
12
+ hasBlur: false
13
+ };
14
+ }
15
+ return {
16
+ blurDataUrl: image.blurDataUrl || "",
17
+ blurColor: image.blurColor || "#E5E7EB",
18
+ ...image.blurHash ? { blurHash: image.blurHash } : {},
19
+ hasBlur: Boolean(image.blurDataUrl || image.blurHash)
20
+ };
21
+ }
22
+ function getImagePropsWithBlur(image) {
23
+ if (!_optionalChain([image, 'optionalAccess', _ => _.url])) {
24
+ return null;
25
+ }
26
+ const blurData = getBlurData(image);
27
+ return {
28
+ src: image.url,
29
+ alt: image.altText || "",
30
+ width: image.width || 1920,
31
+ height: image.height || 1080,
32
+ ...blurData.blurDataUrl && {
33
+ placeholder: "blur",
34
+ blurDataURL: blurData.blurDataUrl
35
+ }
36
+ };
37
+ }
38
+ function getBackgroundPropsWithBlur(image) {
39
+ if (!_optionalChain([image, 'optionalAccess', _2 => _2.url])) {
40
+ return {
41
+ backgroundColor: "#E5E7EB"
42
+ };
43
+ }
44
+ const blurData = getBlurData(image);
45
+ return {
46
+ backgroundColor: blurData.blurColor,
47
+ backgroundImage: formatCssUrl(image.url),
48
+ backgroundSize: "cover",
49
+ backgroundPosition: "center",
50
+ backgroundRepeat: "no-repeat"
51
+ };
52
+ }
53
+ function getBlurPlaceholderStyle(image) {
54
+ const blurData = getBlurData(image);
55
+ if (!blurData.blurDataUrl) {
56
+ return {
57
+ backgroundColor: blurData.blurColor
58
+ };
59
+ }
60
+ return {
61
+ backgroundColor: blurData.blurColor,
62
+ backgroundImage: formatCssUrl(blurData.blurDataUrl),
63
+ backgroundSize: "cover",
64
+ backgroundPosition: "center",
65
+ filter: "blur(20px)",
66
+ transform: "scale(1.1)"
67
+ };
68
+ }
69
+ function hasBlurData(image) {
70
+ return Boolean(_optionalChain([image, 'optionalAccess', _3 => _3.blurDataUrl]) || _optionalChain([image, 'optionalAccess', _4 => _4.blurColor]) || _optionalChain([image, 'optionalAccess', _5 => _5.blurHash]));
71
+ }
72
+ function getBulkBlurData(images) {
73
+ return images.map(getBlurData);
74
+ }
75
+ function createSrcSetWithBlur(image) {
76
+ if (!_optionalChain([image, 'optionalAccess', _6 => _6.url])) return "";
77
+ if (image.width && image.width > 0) {
78
+ return `${image.url} ${image.width}w`;
79
+ }
80
+ return image.url;
81
+ }
82
+ function preloadImageWithBlur(image) {
83
+ if (!_optionalChain([image, 'optionalAccess', _7 => _7.url]) || typeof document === "undefined" || !document.head) return;
84
+ const existingLinks = document.head.querySelectorAll(
85
+ 'link[rel="preload"][as="image"]'
86
+ );
87
+ for (let i = 0; i < existingLinks.length; i++) {
88
+ const el = existingLinks[i];
89
+ if (el.getAttribute("href") === image.url || el.href === image.url) {
90
+ return;
91
+ }
92
+ }
93
+ const link = document.createElement("link");
94
+ link.rel = "preload";
95
+ link.as = "image";
96
+ link.href = image.url;
97
+ document.head.appendChild(link);
98
+ }
99
+ function extractImageUrls(image) {
100
+ if (!_optionalChain([image, 'optionalAccess', _8 => _8.url])) return [];
101
+ return [image.url];
102
+ }
103
+ function decodeBlurHashToDataURL(hash, width = 32, height = 32, punch = 1) {
104
+ if (!hash || typeof document === "undefined") return null;
105
+ const validation = _blurhash.isBlurhashValid.call(void 0, hash);
106
+ if (!validation.result) return null;
107
+ try {
108
+ const pixels = _blurhash.decode.call(void 0, hash, width, height, punch);
109
+ const canvas = document.createElement("canvas");
110
+ canvas.width = width;
111
+ canvas.height = height;
112
+ const ctx = canvas.getContext("2d");
113
+ if (!ctx) return null;
114
+ const imageData = ctx.createImageData(width, height);
115
+ imageData.data.set(pixels);
116
+ ctx.putImageData(imageData, 0, 0);
117
+ return canvas.toDataURL("image/png");
118
+ } catch (e) {
119
+ return null;
120
+ }
121
+ }
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+
134
+ exports.getBlurData = getBlurData; exports.getImagePropsWithBlur = getImagePropsWithBlur; exports.getBackgroundPropsWithBlur = getBackgroundPropsWithBlur; exports.getBlurPlaceholderStyle = getBlurPlaceholderStyle; exports.hasBlurData = hasBlurData; exports.getBulkBlurData = getBulkBlurData; exports.createSrcSetWithBlur = createSrcSetWithBlur; exports.preloadImageWithBlur = preloadImageWithBlur; exports.extractImageUrls = extractImageUrls; exports.decodeBlurHashToDataURL = decodeBlurHashToDataURL;
135
+ //# sourceMappingURL=chunk-FP5YIWG5.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["e:\\Personal-Projects\\image-upload-kit\\dist\\chunk-FP5YIWG5.cjs"],"names":[],"mappings":"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","file":"E:\\Personal-Projects\\image-upload-kit\\dist\\chunk-FP5YIWG5.cjs","sourcesContent":[null]}