markdown-exit-s3-image 0.0.1 → 0.0.2

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 (2) hide show
  1. package/dist/index.mjs +27 -25
  2. package/package.json +7 -2
package/dist/index.mjs CHANGED
@@ -138,6 +138,12 @@ function image(md, userOptions) {
138
138
  const cache = cachePath ? new ImageCache(cachePath) : null;
139
139
  let cacheLoaded = false;
140
140
  let imageCount = 0;
141
+ if (cache && !cacheLoaded) {
142
+ cache.load().catch((err) => {
143
+ console.error("[ImageCache] Failed to load cache:", err);
144
+ });
145
+ cacheLoaded = true;
146
+ }
141
147
  process.once("beforeExit", () => {
142
148
  if (cache) cache.save();
143
149
  });
@@ -150,10 +156,6 @@ function image(md, userOptions) {
150
156
  if (!src.startsWith("http")) return imageRule(tokens, idx, info, env, self);
151
157
  if (!isSupportedDomain(src, options.supported_domains)) return imageRule(tokens, idx, info, env, self);
152
158
  if (shouldIgnoreFormat(src, options.ignore_formats)) return imageRule(tokens, idx, info, env, self);
153
- if (!cacheLoaded && cache) {
154
- await cache.load();
155
- cacheLoaded = true;
156
- }
157
159
  try {
158
160
  if (cache) {
159
161
  const cached = cache.get(src);
@@ -165,9 +167,14 @@ function image(md, userOptions) {
165
167
  const response = await fetch(src);
166
168
  const image$1 = sharp(Buffer.from(await response.arrayBuffer()));
167
169
  const { width, height } = await image$1.metadata();
168
- const { data: thumbnailBuffer, info: thumbnailInfo } = await image$1.resize(100, 100, { fit: "inside" }).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
169
- const placeholderUrl = rgbaToDataURL(thumbnailInfo.width, thumbnailInfo.height, new Uint8Array(thumbnailBuffer));
170
- if (cache) cache.set(src, {
170
+ let placeholderUrl = "";
171
+ try {
172
+ const { data: thumbnailBuffer, info: thumbnailInfo } = await image$1.resize(100, 100, { fit: "inside" }).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
173
+ placeholderUrl = rgbaToDataURL(thumbnailInfo.width, thumbnailInfo.height, new Uint8Array(thumbnailBuffer));
174
+ } catch (thumbErr) {
175
+ console.warn(`[ImageCache] Failed to generate placeholder for ${src}: ${thumbErr instanceof Error ? thumbErr.message : String(thumbErr)}`);
176
+ }
177
+ if (cache && placeholderUrl) cache.set(src, {
171
178
  width,
172
179
  height,
173
180
  placeholder: placeholderUrl
@@ -189,12 +196,17 @@ function generateSrcset(src, width, srcsetWidths) {
189
196
  function buildImageHTML(alt, src, options, imageIndex, width, height, dataURL) {
190
197
  const srcset = generateSrcset(src, width, options.progressive.srcset_widths);
191
198
  const shouldLazyLoad = options.lazy.enable && imageIndex > options.lazy.skip_first;
192
- /**
193
- * 4. 返回包装后的 HTML
194
- * - 外层 div 控制最大宽度并占用占位空间
195
- * - aspect-ratio 确保容器高度在图片加载前就已确定
196
- * - background-image 放置低分辨率模糊预览图 (dataURL)
197
- */
199
+ const mainImgAttrs = [
200
+ `src="${src}"`,
201
+ `alt="${alt}"`,
202
+ `width="${width}"`,
203
+ `height="${height}"`,
204
+ `srcset="${srcset}"`,
205
+ `sizes="${options.progressive.sizes || `(max-width: ${width}px) 100vw, ${width}px`}"`,
206
+ shouldLazyLoad ? "loading=\"lazy\" decoding=\"async\"" : "fetchpriority=\"high\"",
207
+ `style="width: 100%; height: auto; display: block; transition: opacity 0.4s; opacity: 0;"`,
208
+ `onload="this.style.opacity=1; this.parentElement.style.backgroundImage='none';"`
209
+ ].filter(Boolean).join(" ");
198
210
  return `
199
211
  <div class="img-container" style="
200
212
  position: relative;
@@ -202,21 +214,11 @@ function buildImageHTML(alt, src, options, imageIndex, width, height, dataURL) {
202
214
  aspect-ratio: ${width} / ${height};
203
215
  max-width: ${width}px;
204
216
  width: 100%;
205
- background-image: url('${dataURL}');
217
+ ${dataURL ? `background-image: url('${dataURL}');` : ""}
206
218
  background-size: cover;
207
219
  background-repeat: no-repeat;
208
220
  ">
209
- <img ${[
210
- `src="${src}"`,
211
- `alt="${alt}"`,
212
- `width="${width}"`,
213
- `height="${height}"`,
214
- `srcset="${srcset}"`,
215
- `sizes="${options.progressive.sizes || `(max-width: ${width}px) 100vw, ${width}px`}"`,
216
- shouldLazyLoad ? "loading=\"lazy\" decoding=\"async\"" : "fetchpriority=\"high\"",
217
- `style="width: 100%; height: auto; display: block; transition: opacity 0.4s; opacity: 0;"`,
218
- `onload="this.style.opacity=1; this.parentElement.style.backgroundImage='none';"`
219
- ].filter(Boolean).join(" ")}>
221
+ <img ${mainImgAttrs}>
220
222
  </div>
221
223
  `;
222
224
  }
package/package.json CHANGED
@@ -2,8 +2,12 @@
2
2
  "name": "markdown-exit-s3-image",
3
3
  "type": "module",
4
4
  "author": "gnix_aij",
5
- "version": "0.0.1",
5
+ "version": "0.0.2",
6
6
  "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/Efterklang/markdown-exit-s3-image.git"
10
+ },
7
11
  "exports": {
8
12
  ".": {
9
13
  "types": "./dist/index.d.mts",
@@ -36,6 +40,7 @@
36
40
  "devDependencies": {
37
41
  "@tsconfig/node20": "^20.1.8",
38
42
  "@types/node": "^24.10.1",
39
- "tsdown": "^0.16.6"
43
+ "tsdown": "^0.16.6",
44
+ "typescript": "^5.9.3"
40
45
  }
41
46
  }