ochre-sdk 1.0.72 → 1.0.74

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.
@@ -151,6 +151,46 @@ function stringLiteral(value) {
151
151
  return `"${value.replaceAll("\"", "\"\"")}"`;
152
152
  }
153
153
  /**
154
+ * XQuery prolog declaring `local:omit-supplemental`, which drops every element
155
+ * carrying `supplemental="true"` from a node sequence, at any depth.
156
+ *
157
+ * Subtrees without a supplemental descendant are returned by reference, so
158
+ * nodes are only copied along the path leading to an omitted element. The
159
+ * lookahead walks the attribute axis (`//@supplemental`) rather than testing
160
+ * every element, which measures around three times faster on large documents.
161
+ *
162
+ * Must be declared before any query body that calls {@link omitSupplemental}.
163
+ */
164
+ const SUPPLEMENTAL_XQUERY_PROLOG = `declare function local:omit-supplemental($nodes as node()*) as node()* {
165
+ for $node in $nodes
166
+ return
167
+ if ($node instance of element())
168
+ then
169
+ if ($node/@supplemental = "true")
170
+ then ()
171
+ else if (empty($node//@supplemental[. = "true"]))
172
+ then $node
173
+ else element { node-name($node) } {
174
+ $node/@*,
175
+ local:omit-supplemental($node/node())
176
+ }
177
+ else $node
178
+ };`;
179
+ /**
180
+ * Wrap an XQuery node expression so supplemental nodes are omitted from it
181
+ * @param expression - The XQuery expression returning the nodes to filter
182
+ * @returns The wrapped XQuery expression
183
+ */
184
+ function omitSupplemental(expression) {
185
+ return `local:omit-supplemental(${expression})`;
186
+ }
187
+ /**
188
+ * XQuery predicate keeping only nodes that are neither supplemental themselves
189
+ * nor nested inside a supplemental node. Use it when aggregating over nodes
190
+ * instead of returning them.
191
+ */
192
+ const NOT_SUPPLEMENTAL_PREDICATE = "[not(ancestor-or-self::*[@supplemental = \"true\"])]";
193
+ /**
154
194
  * Flatten a properties array
155
195
  * @param properties - The properties to flatten
156
196
  * @returns The flattened properties
@@ -169,4 +209,4 @@ function flattenProperties(properties) {
169
209
  return result;
170
210
  }
171
211
  //#endregion
172
- export { createSchemaValidationError, flattenProperties, getErrorOutput, isPseudoUuid, stringLiteral };
212
+ export { NOT_SUPPLEMENTAL_PREDICATE, SUPPLEMENTAL_XQUERY_PROLOG, createSchemaValidationError, flattenProperties, getErrorOutput, isPseudoUuid, omitSupplemental, stringLiteral };
@@ -1,11 +1,6 @@
1
- import { XMLData as XMLData$1, XMLDataItem as XMLDataItem$1, XMLGalleryData as XMLGalleryData$1, XMLItemLinksData as XMLItemLinksData$1, XMLLink as XMLLink$1, XMLOcrMatchesData as XMLOcrMatchesData$1, XMLSetItemsData as XMLSetItemsData$1, XMLWebsiteData as XMLWebsiteData$1 } from "./types.mjs";
1
+ import { XMLData as XMLData$1, XMLDataItem as XMLDataItem$1, XMLGalleryData as XMLGalleryData$1, XMLItemLinksData as XMLItemLinksData$1, XMLLink as XMLLink$1, XMLSetItemsData as XMLSetItemsData$1, XMLWebsiteData as XMLWebsiteData$1 } from "./types.mjs";
2
2
  import * as v from "valibot";
3
3
  //#region src/xml/schemas.d.ts
4
- /**
5
- * Schema for validating OCR matches fetched from the OCHRE API
6
- * @internal
7
- */
8
- declare const XMLOcrMatchesData: v.GenericSchema<unknown, XMLOcrMatchesData$1>;
9
4
  declare const XMLLink: v.GenericSchema<unknown, XMLLink$1>;
10
5
  declare const XMLDataItem: v.GenericSchema<unknown, XMLDataItem$1>;
11
6
  declare const XMLItemLinksData: v.GenericSchema<unknown, XMLItemLinksData$1>;
@@ -14,4 +9,4 @@ declare const XMLSetItemsData: v.GenericSchema<unknown, XMLSetItemsData$1>;
14
9
  declare const XMLData: v.GenericSchema<unknown, XMLData$1>;
15
10
  declare const XMLWebsiteData: v.GenericSchema<unknown, XMLWebsiteData$1>;
16
11
  //#endregion
17
- export { XMLData, XMLDataItem, XMLGalleryData, XMLItemLinksData, XMLLink, XMLOcrMatchesData, XMLSetItemsData, XMLWebsiteData };
12
+ export { XMLData, XMLDataItem, XMLGalleryData, XMLItemLinksData, XMLLink, XMLSetItemsData, XMLWebsiteData };
@@ -224,42 +224,6 @@ const XMLImageMap = v.object({
224
224
  width: XMLNumber,
225
225
  height: XMLNumber
226
226
  }, "XMLImageMap: Shape error");
227
- const XMLOcrString = v.object({
228
- HPOS: XMLNumber,
229
- VPOS: XMLNumber,
230
- WIDTH: XMLNumber,
231
- HEIGHT: XMLNumber,
232
- CONTENT: v.string("XMLOcrString: CONTENT is string and required"),
233
- VERTICES: v.optional(v.string("XMLOcrString: VERTICES is string and optional"))
234
- }, "XMLOcrString: Shape error");
235
- const XMLOcrTextLine = v.object({ string: v.optional(v.array(XMLOcrString, "XMLOcrTextLine: string is array of XMLOcrString")) }, "XMLOcrTextLine: Shape error");
236
- const XMLOcrTextBlock = v.object({ TextLine: v.optional(v.array(XMLOcrTextLine, "XMLOcrTextBlock: TextLine is array of XMLOcrTextLine")) }, "XMLOcrTextBlock: Shape error");
237
- const XMLOcrPage = v.object({
238
- n: XMLOptionalNumber,
239
- fileName: v.optional(v.string("XMLOcrPage: fileName is string and optional")),
240
- WIDTH: XMLOptionalNumber,
241
- HEIGHT: XMLOptionalNumber,
242
- TextBlock: v.optional(v.array(XMLOcrTextBlock, "XMLOcrPage: TextBlock is array of XMLOcrTextBlock"))
243
- }, "XMLOcrPage: Shape error");
244
- const XMLOcr = v.object({ Page: v.optional(v.array(XMLOcrPage, "XMLOcr: Page is array of XMLOcrPage")) }, "XMLOcr: Shape error");
245
- const XMLOcrMatch = v.object({
246
- resourceUuid: v.optional(v.string("XMLOcrMatch: resourceUuid is string and optional")),
247
- n: XMLOptionalNumber,
248
- fileName: v.optional(v.string("XMLOcrMatch: fileName is string and optional")),
249
- WIDTH: XMLOptionalNumber,
250
- HEIGHT: XMLOptionalNumber,
251
- string: v.optional(v.array(XMLOcrString, "XMLOcrMatch: string is array of XMLOcrString"))
252
- }, "XMLOcrMatch: Shape error");
253
- const XMLOcrMatchItem = v.object({
254
- uuid: v.pipe(v.string("XMLOcrMatchItem: uuid is string and required"), v.check(isPseudoUuid, "XMLOcrMatchItem: uuid is not a valid pseudo-UUID")),
255
- matchCount: XMLNumber,
256
- ocrMatch: v.optional(v.array(XMLOcrMatch, "XMLOcrMatchItem: ocrMatch is array of XMLOcrMatch"))
257
- }, "XMLOcrMatchItem: Shape error");
258
- /**
259
- * Schema for validating OCR matches fetched from the OCHRE API
260
- * @internal
261
- */
262
- const XMLOcrMatchesData = v.object({ result: v.object({ ochre: v.object({ ocrMatches: v.optional(v.object({ ocrItem: v.optional(v.array(XMLOcrMatchItem, "XMLOcrMatchesData: ocrItem is array of XMLOcrMatchItem")) })) }) }) }, "XMLOcrMatchesData: Shape error");
263
227
  const XMLNote = v.object({
264
228
  content: v.optional(XMLContent.entries.content),
265
229
  payload: v.optional(v.string("XMLNote: payload is string and optional")),
@@ -680,7 +644,6 @@ const XMLResource = v.object({
680
644
  width: XMLOptionalNumber,
681
645
  image: v.optional(XMLImage),
682
646
  imagemap: v.optional(XMLImageMap),
683
- ocr: v.optional(XMLOcr),
684
647
  document: v.optional(XMLContent),
685
648
  coordinates: v.optional(XMLCoordinates),
686
649
  periods: v.optional(v.object({ period: v.array(XMLPeriod) })),
@@ -832,7 +795,6 @@ const XMLWebsiteResource = v.lazy(() => v.object({
832
795
  width: XMLOptionalNumber,
833
796
  image: v.optional(XMLImage),
834
797
  imagemap: v.optional(XMLImageMap),
835
- ocr: v.optional(XMLOcr),
836
798
  document: v.optional(XMLContent),
837
799
  coordinates: v.optional(XMLCoordinates),
838
800
  periods: v.optional(v.object({ period: v.array(XMLPeriod) })),
@@ -966,4 +928,4 @@ const XMLWebsiteData = v.object({ result: v.object({ ochre: v.object({
966
928
  tree: v.array(XMLWebsiteTree)
967
929
  }, "XMLWebsiteData: ochre is object with website tree") }, "XMLWebsiteData: result is object with ochre") }, "XMLWebsiteData: Shape error");
968
930
  //#endregion
969
- export { XMLData, XMLDataItem, XMLGalleryData, XMLItemLinksData, XMLLink, XMLOcrMatchesData, XMLSetItemsData, XMLWebsiteData };
931
+ export { XMLData, XMLDataItem, XMLGalleryData, XMLItemLinksData, XMLLink, XMLSetItemsData, XMLWebsiteData };
@@ -182,48 +182,6 @@ type XMLImageMap = {
182
182
  width: XMLNumber;
183
183
  height: XMLNumber;
184
184
  };
185
- type XMLOcrString = {
186
- HPOS: XMLNumber;
187
- VPOS: XMLNumber;
188
- WIDTH: XMLNumber;
189
- HEIGHT: XMLNumber;
190
- CONTENT: string;
191
- VERTICES?: string;
192
- };
193
- type XMLOcrTextLine = {
194
- string?: Array<XMLOcrString>;
195
- };
196
- type XMLOcrTextBlock = {
197
- TextLine?: Array<XMLOcrTextLine>;
198
- };
199
- type XMLOcrPage = {
200
- n?: XMLNumber;
201
- fileName?: string;
202
- WIDTH?: XMLNumber;
203
- HEIGHT?: XMLNumber;
204
- TextBlock?: Array<XMLOcrTextBlock>;
205
- };
206
- type XMLOcr = {
207
- Page?: Array<XMLOcrPage>;
208
- };
209
- type XMLOcrMatch = Omit<XMLOcrPage, "TextBlock"> & {
210
- resourceUuid?: string;
211
- string?: Array<XMLOcrString>;
212
- };
213
- type XMLOcrMatchItem = {
214
- uuid: string;
215
- matchCount: XMLNumber;
216
- ocrMatch?: Array<XMLOcrMatch>;
217
- };
218
- type XMLOcrMatchesData = {
219
- result: {
220
- ochre: {
221
- ocrMatches?: {
222
- ocrItem?: Array<XMLOcrMatchItem>;
223
- };
224
- };
225
- };
226
- };
227
185
  type XMLNote = Partial<XMLContent> & XMLString & {
228
186
  noteNo?: XMLNumber;
229
187
  title?: string;
@@ -605,7 +563,6 @@ type XMLResource = XMLBaseItem & {
605
563
  width?: XMLNumber;
606
564
  image?: XMLImage;
607
565
  imagemap?: XMLImageMap;
608
- ocr?: XMLOcr;
609
566
  document?: XMLContent;
610
567
  coordinates?: XMLCoordinates;
611
568
  periods?: {
@@ -963,4 +920,4 @@ type XMLWebsiteData = {
963
920
  };
964
921
  };
965
922
  //#endregion
966
- export { XMLBaseItem, XMLBibliography, XMLBoolean, XMLConcept, XMLContent, XMLContext, XMLContextGroup, XMLContextItem, XMLContextValue, XMLCoordinate, XMLCoordinates, XMLCoordinatesSource, XMLData, XMLDataItem, XMLDictionaryUnit, XMLEmptyContext, XMLEvent, XMLGallery, XMLGalleryData, XMLHeading, XMLHeadingItemCategory, XMLIdentification, XMLImage, XMLImageMap, XMLImageMapArea, XMLInterpretation, XMLItemCategory, XMLItemLinks, XMLItemLinksData, XMLLicense, XMLLink, XMLLinkedBaseItem, XMLLinkedBibliography, XMLLinkedConcept, XMLLinkedPeriod, XMLLinkedPerson, XMLLinkedPropertyValue, XMLLinkedPropertyVariable, XMLLinkedResource, XMLLinkedSet, XMLLinkedSpatialUnit, XMLLinkedText, XMLLinkedTree, XMLMetadata, XMLNote, XMLNumber, XMLObservation, XMLOcr, XMLOcrMatch, XMLOcrMatchItem, XMLOcrMatchesData, XMLOcrPage, XMLOcrString, XMLOcrTextBlock, XMLOcrTextLine, XMLPeriod, XMLPerson, XMLProperty, XMLPropertyRelation, XMLPropertyValue, XMLPropertyVariable, XMLRecursiveItemCategory, XMLResource, XMLRichTextEnvelope, XMLSection, XMLSet, XMLSetItems, XMLSetItemsData, XMLSimplifiedProperty, XMLSpatialUnit, XMLString, XMLText, XMLTree, XMLWebsiteContext, XMLWebsiteContextItem, XMLWebsiteContextLevel, XMLWebsiteData, XMLWebsiteFilterContext, XMLWebsiteFilterContextItem, XMLWebsiteOptions, XMLWebsiteProperties, XMLWebsiteResource, XMLWebsiteResourceGroup, XMLWebsiteResourceItem, XMLWebsiteScope, XMLWebsiteSegment, XMLWebsiteStyle, XMLWebsiteTree };
923
+ export { XMLBaseItem, XMLBibliography, XMLBoolean, XMLConcept, XMLContent, XMLContext, XMLContextGroup, XMLContextItem, XMLContextValue, XMLCoordinate, XMLCoordinates, XMLCoordinatesSource, XMLData, XMLDataItem, XMLDictionaryUnit, XMLEmptyContext, XMLEvent, XMLGallery, XMLGalleryData, XMLHeading, XMLHeadingItemCategory, XMLIdentification, XMLImage, XMLImageMap, XMLImageMapArea, XMLInterpretation, XMLItemCategory, XMLItemLinks, XMLItemLinksData, XMLLicense, XMLLink, XMLLinkedBaseItem, XMLLinkedBibliography, XMLLinkedConcept, XMLLinkedPeriod, XMLLinkedPerson, XMLLinkedPropertyValue, XMLLinkedPropertyVariable, XMLLinkedResource, XMLLinkedSet, XMLLinkedSpatialUnit, XMLLinkedText, XMLLinkedTree, XMLMetadata, XMLNote, XMLNumber, XMLObservation, XMLPeriod, XMLPerson, XMLProperty, XMLPropertyRelation, XMLPropertyValue, XMLPropertyVariable, XMLRecursiveItemCategory, XMLResource, XMLRichTextEnvelope, XMLSection, XMLSet, XMLSetItems, XMLSetItemsData, XMLSimplifiedProperty, XMLSpatialUnit, XMLString, XMLText, XMLTree, XMLWebsiteContext, XMLWebsiteContextItem, XMLWebsiteContextLevel, XMLWebsiteData, XMLWebsiteFilterContext, XMLWebsiteFilterContextItem, XMLWebsiteOptions, XMLWebsiteProperties, XMLWebsiteResource, XMLWebsiteResourceGroup, XMLWebsiteResourceItem, XMLWebsiteScope, XMLWebsiteSegment, XMLWebsiteStyle, XMLWebsiteTree };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ochre-sdk",
3
- "version": "1.0.72",
3
+ "version": "1.0.74",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Node.js library for working with OCHRE (Online Cultural and Historical Research Environment) data",
@@ -51,11 +51,12 @@
51
51
  "valibot": "^1.4.2"
52
52
  },
53
53
  "devDependencies": {
54
- "@antfu/eslint-config": "^9.2.0",
54
+ "@antfu/eslint-config": "^9.3.0",
55
55
  "@types/node": "^24.13.3",
56
- "bumpp": "^12.1.1",
56
+ "bumpp": "^12.2.0",
57
57
  "eslint": "^10.8.0",
58
- "knip": "^6.31.0",
58
+ "eslint-plugin-erasable-syntax-only": "^0.4.2",
59
+ "knip": "^6.32.0",
59
60
  "oxfmt": "^0.62.0",
60
61
  "tsdown": "^0.22.14",
61
62
  "typescript": "^6.0.3",
@@ -1,44 +0,0 @@
1
- import { OcrMatch } from "../types/index.mjs";
2
- import { FetchFunction } from "../parsers/helpers.mjs";
3
- //#region src/fetchers/ocr-matches.d.ts
4
- /**
5
- * Fetches the locations of OCR text matches within OCHRE resources
6
- *
7
- * Matching mirrors the `ocr` Set item query target, so the same value and match
8
- * mode that selected an item will locate its hits. `matchCountsByUuid` reports
9
- * the untruncated count, which can exceed the returned matches when
10
- * `maxMatchesPerItem` caps them.
11
- *
12
- * @param parameters - The parameters for the fetch
13
- * @param parameters.uuids - The resource UUIDs to search, typically from a filtered Set item fetch
14
- * @param parameters.value - The search value
15
- * @param parameters.matchMode - Whether to match loosely (stemming and wildcards) or on whole OCR words, defaults to "includes"
16
- * @param parameters.isCaseSensitive - Whether matching is case sensitive, defaults to false
17
- * @param parameters.maxMatchesPerItem - The cap on returned matches per requested UUID, defaults to 50
18
- * @param options - Options for the fetch
19
- * @param options.fetch - The fetch function to use
20
- * @returns The OCR matches, or null if the fetch/parse fails
21
- */
22
- declare function fetchOcrMatches(parameters: {
23
- uuids: Array<string>;
24
- value: string;
25
- matchMode?: "includes" | "exact";
26
- isCaseSensitive?: boolean;
27
- maxMatchesPerItem?: number;
28
- }, options?: {
29
- fetch?: FetchFunction;
30
- }): Promise<{
31
- matches: Array<OcrMatch>;
32
- matchesByUuid: Record<string, Array<OcrMatch>>;
33
- matchCountsByUuid: Record<string, number>;
34
- error: null;
35
- detailedError: null;
36
- } | {
37
- matches: null;
38
- matchesByUuid: null;
39
- matchCountsByUuid: null;
40
- error: string;
41
- detailedError: string;
42
- }>;
43
- //#endregion
44
- export { fetchOcrMatches };
@@ -1,134 +0,0 @@
1
- import { XML_PARSER_OPTIONS } from "../constants.mjs";
2
- import { createSchemaValidationError, getErrorOutput, stringLiteral } from "../utilities.mjs";
3
- import { buildOcrTermQueryExpressions } from "../query.mjs";
4
- import { ocrMatchesParametersSchema } from "../schemas.mjs";
5
- import { restoreXMLMetadata } from "../xml/metadata.mjs";
6
- import { parseOcrMatches } from "../parsers/index.mjs";
7
- import { XMLOcrMatchesData } from "../xml/schemas.mjs";
8
- import * as v from "valibot";
9
- import { XMLParser } from "fast-xml-parser";
10
- //#region src/fetchers/ocr-matches.ts
11
- /**
12
- * Build an XQuery string to fetch OCR match locations from the OCHRE API
13
- *
14
- * Each OCR word is matched with `cts:contains` against the same per-term CTS
15
- * queries the Set item filter compiles, so hit locations always agree with what
16
- * the filter matched — including stemming and wildcards, which cannot be
17
- * reproduced outside MarkLogic.
18
- *
19
- * @param parameters - The parameters for the fetch
20
- * @param parameters.uuids - The resource UUIDs to search
21
- * @param parameters.termQueryExpressions - One CTS query expression per search term, in word order
22
- * @param parameters.maxMatchesPerItem - The cap on returned matches per requested UUID
23
- * @returns An XQuery string
24
- */
25
- function buildXQuery(parameters) {
26
- const { uuids, termQueryExpressions, maxMatchesPerItem } = parameters;
27
- return `xquery version "1.0-ml";
28
-
29
- declare variable $uuids := (${Array.from(uuids, (uuid) => stringLiteral(uuid)).join(", ")});
30
-
31
- declare variable $termQueries := (
32
- ${termQueryExpressions.join(",\n ")}
33
- );
34
-
35
- declare variable $termCount := ${termQueryExpressions.length};
36
-
37
- <ochre>{
38
- <ocrMatches>{
39
- for $uuid in $uuids
40
- let $matches :=
41
- for $page in doc($uuid)//ocr/Page
42
- let $words := $page//TextLine/string
43
- let $wordCount := count($words)
44
- let $resourceUuid := string($page/ancestor::resource[1]/@uuid)
45
- for $word at $index in $words
46
- where $index + $termCount - 1 le $wordCount
47
- and (every $offset in (1 to $termCount)
48
- satisfies cts:contains($words[$index + $offset - 1], $termQueries[$offset]))
49
- return <ocrMatch resourceUuid="{$resourceUuid}">{
50
- $page/@n, $page/@fileName, $page/@WIDTH, $page/@HEIGHT,
51
- subsequence($words, $index, $termCount)
52
- }</ocrMatch>
53
- return <ocrItem uuid="{$uuid}" matchCount="{count($matches)}">{
54
- subsequence($matches, 1, ${maxMatchesPerItem})
55
- }</ocrItem>
56
- }</ocrMatches>
57
- }</ochre>`;
58
- }
59
- /**
60
- * Fetches the locations of OCR text matches within OCHRE resources
61
- *
62
- * Matching mirrors the `ocr` Set item query target, so the same value and match
63
- * mode that selected an item will locate its hits. `matchCountsByUuid` reports
64
- * the untruncated count, which can exceed the returned matches when
65
- * `maxMatchesPerItem` caps them.
66
- *
67
- * @param parameters - The parameters for the fetch
68
- * @param parameters.uuids - The resource UUIDs to search, typically from a filtered Set item fetch
69
- * @param parameters.value - The search value
70
- * @param parameters.matchMode - Whether to match loosely (stemming and wildcards) or on whole OCR words, defaults to "includes"
71
- * @param parameters.isCaseSensitive - Whether matching is case sensitive, defaults to false
72
- * @param parameters.maxMatchesPerItem - The cap on returned matches per requested UUID, defaults to 50
73
- * @param options - Options for the fetch
74
- * @param options.fetch - The fetch function to use
75
- * @returns The OCR matches, or null if the fetch/parse fails
76
- */
77
- async function fetchOcrMatches(parameters, options) {
78
- try {
79
- const { uuids, value, matchMode, isCaseSensitive, maxMatchesPerItem } = v.parse(ocrMatchesParametersSchema, parameters);
80
- const termQueryExpressions = buildOcrTermQueryExpressions({
81
- value,
82
- matchMode,
83
- isCaseSensitive
84
- });
85
- if (termQueryExpressions.length === 0) return {
86
- matches: [],
87
- matchesByUuid: {},
88
- matchCountsByUuid: {},
89
- error: null,
90
- detailedError: null
91
- };
92
- const response = await (options?.fetch ?? fetch)("https://ochre.lib.uchicago.edu/ochre/v2/ochre.php?xquery&xsl=none&lang=\"*\"", {
93
- method: "POST",
94
- body: buildXQuery({
95
- uuids,
96
- termQueryExpressions,
97
- maxMatchesPerItem
98
- }),
99
- headers: { "Content-Type": "application/xquery" }
100
- });
101
- if (!response.ok) throw new Error(`OCHRE API responded with status: ${response.status}`, { cause: response.statusText });
102
- const dataRaw = await response.text();
103
- const data = new XMLParser(XML_PARSER_OPTIONS).parse(dataRaw);
104
- const { success, issues, output } = v.safeParse(XMLOcrMatchesData, data);
105
- if (!success) throw createSchemaValidationError("Failed to parse OCHRE OCR matches", issues);
106
- restoreXMLMetadata(output, data);
107
- const rawOcrItems = output.result.ochre.ocrMatches?.ocrItem ?? [];
108
- const matches = parseOcrMatches(rawOcrItems);
109
- const matchesByUuid = {};
110
- const matchCountsByUuid = {};
111
- for (const uuid of uuids) {
112
- matchesByUuid[uuid] = [];
113
- matchCountsByUuid[uuid] = 0;
114
- }
115
- for (const rawOcrItem of rawOcrItems) matchCountsByUuid[rawOcrItem.uuid] = rawOcrItem.matchCount;
116
- for (const match of matches) matchesByUuid[match.uuid]?.push(match);
117
- return {
118
- matches,
119
- matchesByUuid,
120
- matchCountsByUuid,
121
- error: null,
122
- detailedError: null
123
- };
124
- } catch (error) {
125
- return {
126
- matches: null,
127
- matchesByUuid: null,
128
- matchCountsByUuid: null,
129
- ...getErrorOutput(error, "Unknown error")
130
- };
131
- }
132
- }
133
- //#endregion
134
- export { fetchOcrMatches };