@anaralabs/lector 3.15.0 → 3.15.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 (2) hide show
  1. package/dist/index.js +63 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -401,9 +401,19 @@ function normalizeUnicode(text, matchDiacritics = true) {
401
401
  }
402
402
  var segmenter;
403
403
  function* unicodeReplacements(text, matchDiacritics) {
404
- segmenter ??= new Intl.Segmenter(void 0, { granularity: "grapheme" });
405
404
  for (const match of text.matchAll(/\p{ASCII}?\P{ASCII}+/gu)) {
406
405
  if (normalizeUnicode(match[0], matchDiacritics) === match[0]) continue;
406
+ const prefix = match[0].charCodeAt(0) < 128 ? 1 : 0;
407
+ const code = match[0].charCodeAt(prefix);
408
+ if (match[0].length === prefix + 1 && code >= 64256 && code <= 64262) {
409
+ yield {
410
+ index: match.index + prefix,
411
+ length: 1,
412
+ text: ligatures[code - 64256]
413
+ };
414
+ continue;
415
+ }
416
+ segmenter ??= new Intl.Segmenter(void 0, { granularity: "grapheme" });
407
417
  for (const { segment, index } of segmenter.segment(match[0])) {
408
418
  yield {
409
419
  index: match.index + index,
@@ -7799,6 +7809,10 @@ var useViewportContainer = ({
7799
7809
  if (!st.active) {
7800
7810
  return;
7801
7811
  }
7812
+ if (Math.abs(event.deltaX) > abs) {
7813
+ st.active = false;
7814
+ return;
7815
+ }
7802
7816
  if (now - st.lastTime > WHEEL_INERTIA_GAP_MS) {
7803
7817
  st.active = false;
7804
7818
  return;
@@ -7858,12 +7872,11 @@ var useViewportContainer = ({
7858
7872
  contentPosition,
7859
7873
  containerPosition,
7860
7874
  originZoom: currentZoom,
7875
+ origin: [...origin],
7861
7876
  lastZoom: currentZoom
7862
7877
  };
7863
7878
  });
7864
- if (first) {
7865
- return newMemo;
7866
- }
7879
+ if (first && ms === 1) return newMemo;
7867
7880
  const gestureValuesValid = Number.isFinite(ms) && ms > 0;
7868
7881
  let effectiveScale = ms;
7869
7882
  if (!gestureValuesValid) {
@@ -7882,9 +7895,18 @@ var useViewportContainer = ({
7882
7895
  minZoom,
7883
7896
  maxZoom
7884
7897
  );
7898
+ if (event.type === "wheel") {
7899
+ const previousScale = newMemo.lastZoom / newMemo.originZoom;
7900
+ for (const axis of [0, 1]) {
7901
+ const movement2 = origin[axis] - newMemo.origin[axis];
7902
+ newMemo.contentPosition[axis] += movement2 / previousScale;
7903
+ newMemo.containerPosition[axis] += movement2;
7904
+ newMemo.origin[axis] = origin[axis];
7905
+ }
7906
+ }
7885
7907
  const realMs = newZoom / newMemo.originZoom;
7886
- const newTranslateX = newMemo.contentPosition[0] * realMs - newMemo.containerPosition[0];
7887
- const newTranslateY = newMemo.contentPosition[1] * realMs - newMemo.containerPosition[1];
7908
+ const newTranslateX = newMemo.contentPosition[0] * realMs - newMemo.containerPosition[0] - (origin[0] - newMemo.origin[0]);
7909
+ const newTranslateY = newMemo.contentPosition[1] * realMs - newMemo.containerPosition[1] - (origin[1] - newMemo.origin[1]);
7888
7910
  transformations.current = {
7889
7911
  zoom: newZoom,
7890
7912
  translateX: newTranslateX,
@@ -8066,7 +8088,14 @@ var Pages = ({
8066
8088
  };
8067
8089
  }, [isPinching, virtualizer?.measure, virtualizer?.getVirtualItems]);
8068
8090
  const virtualizerItems = virtualizer?.getVirtualItems() ?? [];
8069
- const items = tempItems.length ? tempItems : virtualizerItems;
8091
+ const items = useMemo(() => {
8092
+ if (!tempItems.length) return virtualizerItems;
8093
+ const combined = new Map(
8094
+ virtualizerItems.map((item) => [item.index, item])
8095
+ );
8096
+ for (const item of tempItems) combined.set(item.index, item);
8097
+ return [...combined.values()].sort((a, b) => a.index - b.index);
8098
+ }, [tempItems, virtualizerItems]);
8070
8099
  useVisiblePage({
8071
8100
  items,
8072
8101
  // Pass through nullish (pre-measure) rather than coercing to 0, so the
@@ -9284,6 +9313,10 @@ function* runSearch(pages, searchText, options = {}, cooperative = false, budget
9284
9313
  let steps = 0;
9285
9314
  let deadline = cooperative ? performance.now() + budget : 0;
9286
9315
  for (const page of pages) {
9316
+ if (cooperative && performance.now() >= deadline) {
9317
+ yield;
9318
+ deadline = performance.now() + budget;
9319
+ }
9287
9320
  const normalized = normalize(page, options);
9288
9321
  const lower = normalized.text;
9289
9322
  const exactStarts = [];
@@ -9308,6 +9341,9 @@ function* runSearch(pages, searchText, options = {}, cooperative = false, budget
9308
9341
  lastStart = span.start;
9309
9342
  lastEnd = span.end;
9310
9343
  exactCount++;
9344
+ if (maxDistance === 0 && exactCount > limit) {
9345
+ return { exactMatches, fuzzyMatches, hasMoreResults: true };
9346
+ }
9311
9347
  if (exactMatches.length < limit) {
9312
9348
  exactMatches.push(
9313
9349
  createMatch(
@@ -9382,7 +9418,19 @@ async function searchDocumentAsync(pages, searchText, options = {}) {
9382
9418
  throw new DOMException("Search aborted", "AbortError");
9383
9419
  const result = iterator.next();
9384
9420
  if (result.done) return result.value;
9385
- await new Promise((resolve) => setTimeout(resolve, 0));
9421
+ await new Promise((resolve) => {
9422
+ if (typeof MessageChannel === "undefined") {
9423
+ setTimeout(resolve, 0);
9424
+ return;
9425
+ }
9426
+ const channel = new MessageChannel();
9427
+ channel.port1.onmessage = () => {
9428
+ channel.port1.close();
9429
+ channel.port2.close();
9430
+ resolve();
9431
+ };
9432
+ channel.port2.postMessage(null);
9433
+ });
9386
9434
  }
9387
9435
  }
9388
9436
 
@@ -9480,10 +9528,16 @@ async function calculateHighlightRects(pageProxy, textMatch) {
9480
9528
  const start = Math.max(0, textMatch.matchIndex - offset3);
9481
9529
  const end = Math.min(length, matchEnd - offset3);
9482
9530
  if (end > start && item.str.slice(start, end).trim()) {
9531
+ let style = styles[item.fontName];
9532
+ if (style?.fontFamily && !style.vertical && (start > 0 || end < length)) {
9533
+ const { TextLayer: TextLayer2 } = await loadPdfJs();
9534
+ const fontFamily = TextLayer2.fontFamilyMap.get(style.fontFamily);
9535
+ if (fontFamily) style = { ...style, fontFamily };
9536
+ }
9483
9537
  matchRects.push(
9484
9538
  getItemRect(
9485
9539
  item,
9486
- styles[item.fontName],
9540
+ style,
9487
9541
  viewport,
9488
9542
  start,
9489
9543
  end,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anaralabs/lector",
3
- "version": "3.15.0",
3
+ "version": "3.15.1",
4
4
  "description": "A headless PDF viewer for React",
5
5
  "author": "andrewdr (https://github.com/andrewdoro)",
6
6
  "license": "MIT",