canvu-react 0.3.12 → 0.3.13

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.
package/dist/react.js CHANGED
@@ -992,7 +992,8 @@ init_shape_builders();
992
992
  var HYDRATION_CACHE_NAME = "canvu-asset-hydration-v1";
993
993
  var DEFAULT_PDF_SCALE = 1.15;
994
994
  var DEFAULT_PDF_PAGE_CONCURRENCY = 2;
995
- var hydrationBlobPromises = /* @__PURE__ */ new Map();
995
+ var hydrationSourcePromises = /* @__PURE__ */ new Map();
996
+ var pdfSourceBlobPromises = /* @__PURE__ */ new Map();
996
997
  function buildImageHydrationKey(assetId) {
997
998
  return `image:${assetId}`;
998
999
  }
@@ -1040,23 +1041,38 @@ async function fetchBlob(url) {
1040
1041
  return null;
1041
1042
  }
1042
1043
  }
1043
- async function getHydrationBlob(key, preferCachedRasters, loader) {
1044
+ async function getHydrationSource(key, preferCachedRasters, loader) {
1044
1045
  const cached = preferCachedRasters ? await readCachedHydrationBlob(key) : null;
1045
- if (cached) return cached;
1046
- const inFlight = hydrationBlobPromises.get(key);
1046
+ if (cached) {
1047
+ return {
1048
+ blob: cached
1049
+ };
1050
+ }
1051
+ const inFlight = hydrationSourcePromises.get(key);
1047
1052
  if (inFlight) return await inFlight;
1048
1053
  const nextPromise = (async () => {
1049
- const blob = await loader();
1050
- if (blob) {
1051
- await writeCachedHydrationBlob(key, blob);
1054
+ const source = await loader();
1055
+ if (source?.blob) {
1056
+ await writeCachedHydrationBlob(key, source.blob);
1052
1057
  }
1053
- return blob;
1058
+ return source;
1054
1059
  })();
1055
- hydrationBlobPromises.set(key, nextPromise);
1060
+ hydrationSourcePromises.set(key, nextPromise);
1056
1061
  try {
1057
1062
  return await nextPromise;
1058
1063
  } finally {
1059
- hydrationBlobPromises.delete(key);
1064
+ hydrationSourcePromises.delete(key);
1065
+ }
1066
+ }
1067
+ async function getPdfSourceBlob(url) {
1068
+ const inFlight = pdfSourceBlobPromises.get(url);
1069
+ if (inFlight) return await inFlight;
1070
+ const nextPromise = fetchBlob(url);
1071
+ pdfSourceBlobPromises.set(url, nextPromise);
1072
+ try {
1073
+ return await nextPromise;
1074
+ } finally {
1075
+ pdfSourceBlobPromises.delete(url);
1060
1076
  }
1061
1077
  }
1062
1078
  function registerObjectUrl(objectUrls, blob) {
@@ -1110,18 +1126,22 @@ async function hydrateImageAssets(requests, resolvedAssetUrls, objectUrls, prefe
1110
1126
  if (!resolvedAsset?.url) {
1111
1127
  return [assetId, null];
1112
1128
  }
1113
- const blob = await getHydrationBlob(
1129
+ const source = await getHydrationSource(
1114
1130
  buildImageHydrationKey(assetId),
1115
1131
  preferCachedRasters,
1116
- async () => await fetchBlob(resolvedAsset.url)
1132
+ async () => {
1133
+ const blob = await fetchBlob(resolvedAsset.url);
1134
+ if (!blob) return null;
1135
+ return { blob };
1136
+ }
1117
1137
  );
1118
- if (!blob) {
1138
+ if (!source?.blob) {
1119
1139
  return [assetId, null];
1120
1140
  }
1121
1141
  return [
1122
1142
  assetId,
1123
1143
  {
1124
- href: registerObjectUrl(objectUrls, blob)
1144
+ href: registerObjectUrl(objectUrls, source.blob)
1125
1145
  }
1126
1146
  ];
1127
1147
  })
@@ -1136,45 +1156,69 @@ async function hydratePdfAssets(requests, resolvedAssetUrls, objectUrls, options
1136
1156
  if (!resolvedAsset?.url) {
1137
1157
  continue;
1138
1158
  }
1139
- const missingPages = [];
1140
- for (const pageNumber of group.pageNumbers) {
1141
- const cacheKey = buildPdfHydrationKey(group.assetId, pageNumber, group.scale);
1142
- const cachedBlob = await readCachedHydrationBlob(cacheKey);
1143
- if (!cachedBlob) {
1144
- missingPages.push(pageNumber);
1159
+ const pageKeys = group.pageNumbers.map((pageNumber) => ({
1160
+ pageNumber,
1161
+ cacheKey: buildPdfHydrationKey(group.assetId, pageNumber, group.scale)
1162
+ }));
1163
+ const pagesToRender = [];
1164
+ for (const { pageNumber, cacheKey } of pageKeys) {
1165
+ const cachedBlob = options.preferCachedRasters ? await readCachedHydrationBlob(cacheKey) : null;
1166
+ if (cachedBlob) {
1167
+ hydratedPages.set(cacheKey, {
1168
+ href: registerObjectUrl(objectUrls, cachedBlob)
1169
+ });
1145
1170
  continue;
1146
1171
  }
1147
- hydratedPages.set(cacheKey, {
1148
- href: registerObjectUrl(objectUrls, cachedBlob)
1149
- });
1150
- }
1151
- if (missingPages.length === 0) {
1152
- continue;
1172
+ if (!hydrationSourcePromises.has(cacheKey)) {
1173
+ pagesToRender.push({ pageNumber, cacheKey });
1174
+ }
1153
1175
  }
1154
- const pdfBlob = await fetchBlob(resolvedAsset.url);
1155
- if (!pdfBlob) {
1156
- continue;
1176
+ if (pagesToRender.length > 0) {
1177
+ const renderPromise = (async () => {
1178
+ const pdfBlob = await getPdfSourceBlob(resolvedAsset.url);
1179
+ if (!pdfBlob) {
1180
+ return /* @__PURE__ */ new Map();
1181
+ }
1182
+ const renderedPages = await loadPdfToStore(pdfBlob, options.imageStore, {
1183
+ scale: group.scale,
1184
+ pageNumbers: pagesToRender.map(({ pageNumber }) => pageNumber),
1185
+ pageConcurrency: options.pdfPageConcurrency
1186
+ });
1187
+ const renderedByPage = /* @__PURE__ */ new Map();
1188
+ for (const renderedPage of renderedPages) {
1189
+ const pageBlob = await options.imageStore.getOriginal(renderedPage.blobId);
1190
+ renderedByPage.set(
1191
+ renderedPage.pageNumber,
1192
+ pageBlob ? {
1193
+ blob: pageBlob,
1194
+ width: renderedPage.width,
1195
+ height: renderedPage.height
1196
+ } : null
1197
+ );
1198
+ }
1199
+ return renderedByPage;
1200
+ })();
1201
+ for (const { pageNumber, cacheKey } of pagesToRender) {
1202
+ const pagePromise = getHydrationSource(
1203
+ cacheKey,
1204
+ options.preferCachedRasters,
1205
+ async () => (await renderPromise).get(pageNumber) ?? null
1206
+ );
1207
+ hydrationSourcePromises.set(cacheKey, pagePromise);
1208
+ }
1157
1209
  }
1158
- const renderedPages = await loadPdfToStore(pdfBlob, options.imageStore, {
1159
- scale: group.scale,
1160
- pageNumbers: missingPages,
1161
- pageConcurrency: options.pdfPageConcurrency
1162
- });
1163
- for (const renderedPage of renderedPages) {
1164
- const cacheKey = buildPdfHydrationKey(
1165
- group.assetId,
1166
- renderedPage.pageNumber,
1167
- group.scale
1210
+ for (const { cacheKey } of pageKeys) {
1211
+ if (hydratedPages.has(cacheKey)) continue;
1212
+ const source = await getHydrationSource(
1213
+ cacheKey,
1214
+ options.preferCachedRasters,
1215
+ async () => null
1168
1216
  );
1169
- const pageBlob = await options.imageStore.getOriginal(renderedPage.blobId);
1170
- if (!pageBlob) {
1171
- continue;
1172
- }
1173
- await writeCachedHydrationBlob(cacheKey, pageBlob);
1217
+ if (!source?.blob) continue;
1174
1218
  hydratedPages.set(cacheKey, {
1175
- href: registerObjectUrl(objectUrls, pageBlob),
1176
- width: renderedPage.width,
1177
- height: renderedPage.height
1219
+ href: registerObjectUrl(objectUrls, source.blob),
1220
+ width: source.width,
1221
+ height: source.height
1178
1222
  });
1179
1223
  }
1180
1224
  }
@@ -1215,7 +1259,9 @@ async function hydrateSceneItemsWithAssets(items, assetStore, options = {}) {
1215
1259
  objectUrls,
1216
1260
  {
1217
1261
  imageStore,
1218
- pdfPageConcurrency}
1262
+ pdfPageConcurrency,
1263
+ preferCachedRasters
1264
+ }
1219
1265
  );
1220
1266
  return {
1221
1267
  items: items.map((item) => {