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