@prose-reader/enhancer-search 1.372.0 → 1.374.0
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/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +9 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@prose-reader/core"),t=require("rxjs"),n=require("rxjs/operators");function r(){let e=globalThis.__PROSE_READER_DEBUG;return e===!0||e===`true`}var i=(e,t)=>typeof e==`boolean`?{enabled:e,options:t}:{enabled:e?.enabled,options:e??t},a=e=>e.at(-1)?.color,o=e=>{if(!e.length)return;if(!e.some(e=>e.color))return[e.map(e=>e.label).join(` `)];let t=``,n=[];for(let r of e)t+=`%c${t?` ${r.label}`:r.label}`,n.push(r.color?`color: ${r.color}`:``);return[t,...n]},s=(e=[],t=r())=>{let n=t,c={enable:e=>{u(e)},namespace:(t,r,o)=>{let c=i(r,o),l=c.options?.color??a(e);return s([...e,{label:`[${t}]`,color:l}],c.enabled??n)},isEnabled:()=>n,debug:()=>{},info:()=>{},log:()=>{},groupCollapsed:()=>{},groupEnd:()=>{},getGroupArgs:t=>{let n=o(e);if(!n)return[t];let[r,...i]=n;return[`${r} ${t}`,...i]},warn:()=>{},error:()=>{}},l=t=>{if(!t){c.debug=()=>{},c.info=()=>{},c.log=()=>{},c.groupCollapsed=()=>{},c.groupEnd=()=>{},c.warn=()=>{},c.error=()=>{};return}let n=o(e)??[];c.debug=Function.prototype.bind.call(console.debug,console,...n),c.info=Function.prototype.bind.call(console.info,console,...n),c.log=Function.prototype.bind.call(console.log,console,...n),c.groupCollapsed=Function.prototype.bind.call(console.groupCollapsed,console),c.groupEnd=Function.prototype.bind.call(console.groupEnd,console),c.warn=Function.prototype.bind.call(console.warn,console,...n),c.error=Function.prototype.bind.call(console.error,console,...n)},u=e=>{n!==e&&(n=e,l(n))};return l(n),c},c=s().namespace(`@prose-reader/enhancer-search`,!0),l=(e,t,n,r)=>{if(e.nodeName===`head`)return;let i=e.childNodes;for(let e=0;e<i.length;e++){let a=i[e];if(a&&(a.hasChildNodes()&&l(a,t,n,r),a.nodeType===3)){let e=a.data.toLowerCase();if(e){let i=null;for(t.lastIndex=0;(i=t.exec(e))!==null;)if(i.index>=0&&a.ownerDocument){let e=a.ownerDocument.createRange();e.setStart(a,i.index),e.setEnd(a,i.index+n),r.push(e)}}}}},u=(e,t)=>{let n=[];return l(e,RegExp(`(${t})`,`gi`),t.length,n),n},d=(e,n,r,i)=>
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@prose-reader/core"),t=require("rxjs"),n=require("rxjs/operators");function r(){let e=globalThis.__PROSE_READER_DEBUG;return e===!0||e===`true`}var i=(e,t)=>typeof e==`boolean`?{enabled:e,options:t}:{enabled:e?.enabled,options:e??t},a=e=>e.at(-1)?.color,o=e=>{if(!e.length)return;if(!e.some(e=>e.color))return[e.map(e=>e.label).join(` `)];let t=``,n=[];for(let r of e)t+=`%c${t?` ${r.label}`:r.label}`,n.push(r.color?`color: ${r.color}`:``);return[t,...n]},s=(e=[],t=r())=>{let n=t,c={enable:e=>{u(e)},namespace:(t,r,o)=>{let c=i(r,o),l=c.options?.color??a(e);return s([...e,{label:`[${t}]`,color:l}],c.enabled??n)},isEnabled:()=>n,debug:()=>{},info:()=>{},log:()=>{},groupCollapsed:()=>{},groupEnd:()=>{},getGroupArgs:t=>{let n=o(e);if(!n)return[t];let[r,...i]=n;return[`${r} ${t}`,...i]},warn:()=>{},error:()=>{}},l=t=>{if(!t){c.debug=()=>{},c.info=()=>{},c.log=()=>{},c.groupCollapsed=()=>{},c.groupEnd=()=>{},c.warn=()=>{},c.error=()=>{};return}let n=o(e)??[];c.debug=Function.prototype.bind.call(console.debug,console,...n),c.info=Function.prototype.bind.call(console.info,console,...n),c.log=Function.prototype.bind.call(console.log,console,...n),c.groupCollapsed=Function.prototype.bind.call(console.groupCollapsed,console),c.groupEnd=Function.prototype.bind.call(console.groupEnd,console),c.warn=Function.prototype.bind.call(console.warn,console,...n),c.error=Function.prototype.bind.call(console.error,console,...n)},u=e=>{n!==e&&(n=e,l(n))};return l(n),c},c=s().namespace(`@prose-reader/enhancer-search`,!0),l=(e,t,n,r)=>{if(e.nodeName===`head`)return;let i=e.childNodes;for(let e=0;e<i.length;e++){let a=i[e];if(a&&(a.hasChildNodes()&&l(a,t,n,r),a.nodeType===3)){let e=a.data.toLowerCase();if(e){let i=null;for(t.lastIndex=0;(i=t.exec(e))!==null;)if(i.index>=0&&a.ownerDocument){let e=a.ownerDocument.createRange();e.setStart(a,i.index),e.setEnd(a,i.index+n),r.push(e)}}}}},u=(e,t)=>{let n=[];return l(e,RegExp(`(${t})`,`gi`),t.length,n),n},d=(e,n,r,i)=>{let a=u(r,i).map(t=>({cfi:e.cfi.generateCfiFromRange(t,n.item)}));return(0,t.of)(a)},f=r=>i=>{let a=r(i),o=(r,i)=>{let o=a.spineItemsManager.get(r);return o?(0,e.deferIdle)(()=>a.renderHeadless(r)).pipe((0,n.switchMap)(r=>{let{doc:s,release:l}=r||{};return s?(0,e.deferIdle)(()=>d(a,o,s,i)).pipe((0,n.finalize)(()=>{l?.()}),(0,n.catchError)(e=>(c.error(e),(0,t.of)([])))):(0,t.of)([])})):(0,t.of)([])},s=e=>(0,t.defer)(()=>{if(e===``)return(0,t.of)([]);let n=a.context.manifest?.spineItems.map((t,n)=>o(n,e))||[];return(0,t.forkJoin)([...n,(0,t.of)([])])}).pipe((0,n.map)(e=>{let t=e.flat();return c.debug(`results`,t),t}));return{...a,__PROSE_READER_ENHANCER_SEARCH:!0,search:{search:s}}};exports.searchEnhancer=f;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../shared/dist/index.js","../package.json","../src/report.ts","../src/search.ts","../src/index.ts"],"sourcesContent":["//#region src/array.ts\nvar e = (e, t) => e === t || e.length === t.length && e.every((e, n) => e === t[n]), t = (e) => e.split(/[#?]/)[0]?.split(\".\").pop()?.trim() || \"\";\nfunction n(e) {\n\tlet t = [];\n\tif (e.length === 0) return \"\";\n\tif (typeof e[0] != \"string\") throw TypeError(`Url must be a string. Received ${e[0]}`);\n\te[0].match(/^[^/:]+:\\/*$/) && e.length > 1 && (e[0] = e.shift() + e[0]), e[0].match(/^file:\\/\\/\\//) ? e[0] = e[0].replace(/^([^/:]+):\\/*/, \"$1:///\") : e[0] = e[0].replace(/^([^/:]+):\\/*/, \"$1://\");\n\tfor (let n = 0; n < e.length; n++) {\n\t\tlet r = e[n];\n\t\tif (typeof r != \"string\") throw TypeError(`Url must be a string. Received ${r}`);\n\t\tr !== \"\" && (n > 0 && (r = r.replace(/^[/]+/, \"\")), r = n < e.length - 1 ? r.replace(/[/]+$/, \"\") : r.replace(/[/]+$/, \"/\"), t.push(r));\n\t}\n\tlet n = t.join(\"/\");\n\tn = n.replace(/\\/(\\?|&|#[^!])/g, \"$1\");\n\tlet r = n.split(\"?\");\n\treturn n = r.shift() + (r.length > 0 ? \"?\" : \"\") + r.join(\"&\"), n;\n}\nfunction r(...e) {\n\treturn n(Array.from(Array.isArray(e[0]) ? e[0] : e));\n}\nfunction i(e) {\n\tlet t = e.split(\"/\");\n\treturn t.pop(), t.join(\"/\");\n}\n//#endregion\n//#region src/contentType.ts\nvar a = (e) => {\n\tswitch (t(e).toLowerCase()) {\n\t\tcase \"png\": return \"image/png\";\n\t\tcase \"jpg\": return \"image/jpg\";\n\t\tcase \"jpeg\": return \"image/jpeg\";\n\t\tcase \"gif\": return \"image/gif\";\n\t\tcase \"webp\": return \"image/webp\";\n\t\tcase \"avif\": return \"image/avif\";\n\t\tcase \"bmp\": return \"image/bmp\";\n\t\tcase \"tif\":\n\t\tcase \"tiff\": return \"image/tiff\";\n\t\tcase \"svg\": return \"image/svg+xml\";\n\t\tcase \"txt\": return \"text/plain\";\n\t\tcase \"xhtml\": return \"application/xhtml+xml\";\n\t\tcase \"mp3\": return \"audio/mpeg\";\n\t\tcase \"m4a\":\n\t\tcase \"m4b\": return \"audio/mp4\";\n\t\tcase \"aac\": return \"audio/aac\";\n\t\tcase \"ogg\":\n\t\tcase \"oga\": return \"audio/ogg\";\n\t\tcase \"wav\": return \"audio/wav\";\n\t\tcase \"flac\": return \"audio/flac\";\n\t\tcase \"opus\": return \"audio/opus\";\n\t}\n}, o = ({ mimeType: e, uri: t }) => (e ?? a(t ?? \"\"))?.startsWith(\"application/xhtml+xml\"), s = (e) => e.startsWith(\"image/\") || e.startsWith(\"audio/\") || e.startsWith(\"video/\"), c = (e) => {\n\tif (!e.length) return;\n\tlet t = e.indexOf(\";\");\n\treturn t >= 0 ? e.substring(0, t) : e;\n}, l = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/, u = /^[A-Za-z0-9_]/, d = /^xml/i, f = /[^A-Za-z0-9_.-]+/g, p = \"_\", m = (e) => e.replace(/^_+|_+$/g, \"\"), h = (e) => m(e.trim().replaceAll(\"/\", \"_\").replace(f, \"_\")), g = (e) => {\n\tif (l.test(e) && !d.test(e)) return e;\n\tlet t = h(e), n = t && !d.test(t) ? t : `${p}${t}`;\n\treturn u.test(n) ? n : `${p}${n}`;\n}, _ = (e, t) => {\n\tlet n = g(e);\n\tif (!t.has(n)) return t.add(n), n;\n\tlet r = 2, i = `${n}-${r}`;\n\tfor (; t.has(i);) r += 1, i = `${n}-${r}`;\n\treturn t.add(i), i;\n}, v = () => {\n\tlet e = /* @__PURE__ */ new Set();\n\treturn (t) => _(t, e);\n}, y = (e) => {\n\tlet t = e.pageSpreadLeft === !0;\n\tif (t !== (e.pageSpreadRight === !0)) return t ? \"left\" : \"right\";\n}, b = (e, t, n) => {\n\tif (Object.is(e, t)) return !0;\n\tif (typeof e != \"object\" || !e || typeof t != \"object\" || !t) return !1;\n\tlet r = Object.keys(e), i = Object.keys(t);\n\tif (r.length !== i.length) return !1;\n\tlet a = n?.customEqual ?? Object.is, o = e, s = t;\n\tfor (let e of r) if (!Object.hasOwn(s, e) || !a(o[e], s[e])) return !1;\n\treturn !0;\n}, x = (e, t) => e.reduce((e, n) => {\n\tlet r = t(n);\n\treturn e[r] || (e[r] = []), e[r].push(n), e;\n}, {});\nfunction S(e, t) {\n\tlet n = { ...e };\n\tfor (let r in t) if (Object.hasOwn(t, r)) {\n\t\tlet i = t[r];\n\t\t(i !== void 0 || !(r in e)) && (n[r] = i);\n\t}\n\treturn n;\n}\n//#endregion\n//#region src/report.ts\nfunction C() {\n\tlet e = globalThis.__PROSE_READER_DEBUG;\n\treturn e === !0 || e === \"true\";\n}\nvar w = (e, t) => typeof e == \"boolean\" ? {\n\tenabled: e,\n\toptions: t\n} : {\n\tenabled: e?.enabled,\n\toptions: e ?? t\n}, T = (e) => e.at(-1)?.color, E = (e) => {\n\tif (!e.length) return;\n\tif (!e.some((e) => e.color)) return [e.map((e) => e.label).join(\" \")];\n\tlet t = \"\", n = [];\n\tfor (let r of e) t += `%c${t ? ` ${r.label}` : r.label}`, n.push(r.color ? `color: ${r.color}` : \"\");\n\treturn [t, ...n];\n}, D = (e = [], t = C()) => {\n\tlet n = t, r = {\n\t\tenable: (e) => {\n\t\t\ta(e);\n\t\t},\n\t\tnamespace: (t, r, i) => {\n\t\t\tlet a = w(r, i), o = a.options?.color ?? T(e);\n\t\t\treturn D([...e, {\n\t\t\t\tlabel: `[${t}]`,\n\t\t\t\tcolor: o\n\t\t\t}], a.enabled ?? n);\n\t\t},\n\t\tisEnabled: () => n,\n\t\tdebug: () => {},\n\t\tinfo: () => {},\n\t\tlog: () => {},\n\t\tgroupCollapsed: () => {},\n\t\tgroupEnd: () => {},\n\t\tgetGroupArgs: (t) => {\n\t\t\tlet n = E(e);\n\t\t\tif (!n) return [t];\n\t\t\tlet [r, ...i] = n;\n\t\t\treturn [`${r} ${t}`, ...i];\n\t\t},\n\t\twarn: () => {},\n\t\terror: () => {}\n\t}, i = (t) => {\n\t\tif (!t) {\n\t\t\tr.debug = () => {}, r.info = () => {}, r.log = () => {}, r.groupCollapsed = () => {}, r.groupEnd = () => {}, r.warn = () => {}, r.error = () => {};\n\t\t\treturn;\n\t\t}\n\t\tlet n = E(e) ?? [];\n\t\tr.debug = Function.prototype.bind.call(console.debug, console, ...n), r.info = Function.prototype.bind.call(console.info, console, ...n), r.log = Function.prototype.bind.call(console.log, console, ...n), r.groupCollapsed = Function.prototype.bind.call(console.groupCollapsed, console), r.groupEnd = Function.prototype.bind.call(console.groupEnd, console), r.warn = Function.prototype.bind.call(console.warn, console, ...n), r.error = Function.prototype.bind.call(console.error, console, ...n);\n\t}, a = (e) => {\n\t\tn !== e && (n = e, i(n));\n\t};\n\treturn i(n), r;\n}, O = D(), k = \"prose-reader-resource-error\", A = (e, t) => {\n\tlet n = e.split(/(\\d+)/), r = t.split(/(\\d+)/);\n\tfor (let e = 0, t = n.length; e < t; e++) if (n[e] !== r[e]) return n[e]?.match(/\\d/) ? (n[e] || \"\") - +(r[e] || \"\") : (n[e] || \"\").localeCompare(r[e] || \"\");\n\treturn 1;\n}, j = (e) => e.endsWith(\"/\") ? e.slice(0, -1) : e, M = (e) => {\n\tlet t = j(e);\n\treturn t.substring(t.lastIndexOf(\"/\") + 1) || t;\n}, N = (e) => {\n\tlet t = e.lastIndexOf(\"/\");\n\treturn t >= 0 ? e.substring(0, t) : \"\";\n}, P = (e) => e.replaceAll(\"&\", \"&\").replaceAll(\"\\\"\", \""\").replaceAll(\"'\", \"'\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\");\n//#endregion\nexport { k as PROSE_READER_RESOURCE_ERROR_INJECTED_META_NAME, O as Report, e as arrayEqual, _ as createUniqueXmlSafeId, g as createXmlSafeId, v as createXmlSafeIdFactory, a as detectMimeTypeFromName, P as escapeXmlAttributeValue, y as getItemSpreadPosition, i as getParentPath, N as getUriBasePath, M as getUriBasename, t as getUrlExtension, x as groupBy, s as isMediaContentMimeType, b as isShallowEqual, o as isXmlBasedMimeType, c as parseContentType, j as removeTrailingSlash, S as shallowMergeIfDefined, A as sortByTitleComparator, r as urlJoin };\n\n//# sourceMappingURL=index.js.map","{\n \"name\": \"@prose-reader/enhancer-search\",\n \"version\": \"1.371.0\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"/dist\"\n ],\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"scripts\": {\n \"start\": \"vite build --watch --mode development\",\n \"build\": \"tsc && vite build\",\n \"test\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@prose-reader/core\": \"^1.371.0\"\n },\n \"peerDependencies\": {\n \"rxjs\": \"*\"\n },\n \"gitHead\": \"4601e14dcacf50b2295cb343582a7ef2c7e1eedc\"\n}\n","import { Report } from \"@prose-reader/shared\"\nimport { name } from \"../package.json\"\n\nconst IS_DEBUG_ENABLED = true\n\nexport const report = Report.namespace(name, IS_DEBUG_ENABLED)\n","import type { Reader, SpineItem } from \"@prose-reader/core\"\nimport { type Observable, of } from \"rxjs\"\nimport type { ResultItem } from \"./types\"\n\nexport type SearchResult = ResultItem[]\n\n/**\n * Walk the subtree accumulating ranges for every match of `regexp`.\n *\n * A full-book search runs this over the rendered document of *every* spine\n * item, so the text-node loop below is the hot path (thousands of text nodes\n * per large chapter). Two things are hoisted out of it to keep the work\n * proportional to the number of matches rather than the number of nodes:\n * - the search regexp is compiled once by the caller and reused across every\n * node (only its `lastIndex` is reset), instead of recompiling per text node,\n * - matches are pushed into a single shared array instead of allocating a new\n * array at each node and spreading child results upward.\n */\nconst collectMatchingRanges = (\n node: Node,\n regexp: RegExp,\n matchLength: number,\n rangeList: Range[],\n) => {\n if (node.nodeName === `head`) return\n\n const nodeList = node.childNodes\n\n for (let i = 0; i < nodeList.length; i++) {\n const subNode = nodeList[i]\n\n if (!subNode) {\n continue\n }\n\n if (subNode.hasChildNodes()) {\n collectMatchingRanges(subNode, regexp, matchLength, rangeList)\n }\n\n if (subNode.nodeType === 3) {\n const content = (subNode as Text).data.toLowerCase()\n if (content) {\n let match: RegExpExecArray | null = null\n regexp.lastIndex = 0\n\n // biome-ignore lint/suspicious/noAssignInExpressions: TODO\n while ((match = regexp.exec(content)) !== null) {\n if (match.index >= 0 && subNode.ownerDocument) {\n const range = subNode.ownerDocument.createRange()\n range.setStart(subNode, match.index)\n range.setEnd(subNode, match.index + matchLength)\n\n rangeList.push(range)\n }\n }\n }\n }\n }\n}\n\nconst searchNodeContainingText = (node: Node, text: string) => {\n const rangeList: Range[] = []\n\n collectMatchingRanges(node, RegExp(`(${text})`, `gi`), text.length, rangeList)\n\n return rangeList\n}\n\nexport const searchInDocument = (\n reader: Reader,\n item: SpineItem,\n doc: Document,\n text: string,\n): Observable<SearchResult> => {\n const ranges = searchNodeContainingText(doc, text)\n\n const newResults = ranges.map((range) => {\n const cfi = reader.cfi.generateCfiFromRange(range, item.item)\n\n return {\n cfi,\n } satisfies ResultItem\n })\n\n return of(newResults)\n}\n","import { deferIdle, type Reader } from \"@prose-reader/core\"\nimport { defer, forkJoin, of } from \"rxjs\"\nimport { catchError, finalize, map, switchMap } from \"rxjs/operators\"\nimport { report } from \"./report\"\nimport type { SearchResult } from \"./search\"\nimport { searchInDocument } from \"./search\"\nimport type { ResultItem, SearchEnhancerAPI } from \"./types\"\n\nexport type { ResultItem, SearchEnhancerAPI, SearchResult }\n\n/**\n * Contract of search enhancer.\n *\n * - At best a result match should be navigable. It means the search needs to\n * be done on a rendered document. This is because rendering can differ from the original\n * item resource. A resource can be something non digestible and very specific (.pdf). The search\n * enhancer is agnostic and can only search into documents.\n */\nexport const searchEnhancer =\n <InheritOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (options: InheritOptions): InheritOutput & SearchEnhancerAPI => {\n const reader = next(options)\n\n const searchForItem = (index: number, text: string) => {\n const item = reader.spineItemsManager.get(index)\n\n if (!item) {\n return of([])\n }\n\n return deferIdle(() => reader.renderHeadless(index)).pipe(\n switchMap((result) => {\n const { doc, release } = result || {}\n\n if (!doc) return of([])\n\n return deferIdle(() =>\n searchInDocument(reader, item, doc, text),\n ).pipe(\n finalize(() => {\n release?.()\n }),\n catchError((e) => {\n report.error(e)\n\n return of([])\n }),\n )\n }),\n )\n }\n\n const search = (text: string) =>\n defer(() => {\n if (text === ``) {\n return of([])\n }\n\n const searches$ =\n reader.context.manifest?.spineItems.map((_, index) =>\n searchForItem(index, text),\n ) || []\n\n return forkJoin([...searches$, of([])])\n }).pipe(\n map((results) => {\n const flattenedResults = results.flat()\n\n report.debug(\"results\", flattenedResults)\n\n return flattenedResults\n }),\n )\n\n return {\n ...reader,\n __PROSE_READER_ENHANCER_SEARCH: true,\n search: {\n search,\n },\n }\n }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../shared/dist/index.js","../package.json","../src/report.ts","../src/search.ts","../src/index.ts"],"sourcesContent":["//#region src/array.ts\nvar e = (e, t) => e === t || e.length === t.length && e.every((e, n) => e === t[n]), t = (e) => e.split(/[#?]/)[0]?.split(\".\").pop()?.trim() || \"\";\nfunction n(e) {\n\tlet t = [];\n\tif (e.length === 0) return \"\";\n\tif (typeof e[0] != \"string\") throw TypeError(`Url must be a string. Received ${e[0]}`);\n\te[0].match(/^[^/:]+:\\/*$/) && e.length > 1 && (e[0] = e.shift() + e[0]), e[0] = e[0].match(/^file:\\/\\/\\//) ? e[0].replace(/^([^/:]+):\\/*/, \"$1:///\") : e[0].replace(/^([^/:]+):\\/*/, \"$1://\");\n\tfor (let n = 0; n < e.length; n++) {\n\t\tlet r = e[n];\n\t\tif (typeof r != \"string\") throw TypeError(`Url must be a string. Received ${r}`);\n\t\tr !== \"\" && (n > 0 && (r = r.replace(/^[/]+/, \"\")), r = n < e.length - 1 ? r.replace(/[/]+$/, \"\") : r.replace(/[/]+$/, \"/\"), t.push(r));\n\t}\n\tlet n = t.join(\"/\");\n\tn = n.replace(/\\/(\\?|&|#[^!])/g, \"$1\");\n\tlet r = n.split(\"?\");\n\treturn n = r.shift() + (r.length > 0 ? \"?\" : \"\") + r.join(\"&\"), n;\n}\nfunction r(...e) {\n\treturn n(Array.from(Array.isArray(e[0]) ? e[0] : e));\n}\nfunction i(e) {\n\tlet t = e.split(\"/\");\n\treturn t.pop(), t.join(\"/\");\n}\n//#endregion\n//#region src/contentType.ts\nvar a = (e) => {\n\tswitch (t(e).toLowerCase()) {\n\t\tcase \"png\": return \"image/png\";\n\t\tcase \"jpg\": return \"image/jpg\";\n\t\tcase \"jpeg\": return \"image/jpeg\";\n\t\tcase \"gif\": return \"image/gif\";\n\t\tcase \"webp\": return \"image/webp\";\n\t\tcase \"avif\": return \"image/avif\";\n\t\tcase \"bmp\": return \"image/bmp\";\n\t\tcase \"tif\":\n\t\tcase \"tiff\": return \"image/tiff\";\n\t\tcase \"svg\": return \"image/svg+xml\";\n\t\tcase \"txt\": return \"text/plain\";\n\t\tcase \"xhtml\": return \"application/xhtml+xml\";\n\t\tcase \"mp3\": return \"audio/mpeg\";\n\t\tcase \"m4a\":\n\t\tcase \"m4b\": return \"audio/mp4\";\n\t\tcase \"aac\": return \"audio/aac\";\n\t\tcase \"ogg\":\n\t\tcase \"oga\": return \"audio/ogg\";\n\t\tcase \"wav\": return \"audio/wav\";\n\t\tcase \"flac\": return \"audio/flac\";\n\t\tcase \"opus\": return \"audio/opus\";\n\t}\n}, o = ({ mimeType: e, uri: t }) => (e ?? a(t ?? \"\"))?.startsWith(\"application/xhtml+xml\"), s = (e) => e.startsWith(\"image/\") || e.startsWith(\"audio/\") || e.startsWith(\"video/\"), c = (e) => {\n\tif (!e.length) return;\n\tlet t = e.indexOf(\";\");\n\treturn t >= 0 ? e.substring(0, t) : e;\n}, l = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/, u = /^[A-Za-z0-9_]/, d = /^xml/i, f = /[^A-Za-z0-9_.-]+/g, p = \"_\", m = (e) => e.replace(/^_+|_+$/g, \"\"), h = (e) => m(e.trim().replaceAll(\"/\", \"_\").replace(f, \"_\")), g = (e) => {\n\tif (l.test(e) && !d.test(e)) return e;\n\tlet t = h(e), n = t && !d.test(t) ? t : `${p}${t}`;\n\treturn u.test(n) ? n : `${p}${n}`;\n}, _ = (e, t) => {\n\tlet n = g(e);\n\tif (!t.has(n)) return t.add(n), n;\n\tlet r = 2, i = `${n}-${r}`;\n\tfor (; t.has(i);) r += 1, i = `${n}-${r}`;\n\treturn t.add(i), i;\n}, v = () => {\n\tlet e = /* @__PURE__ */ new Set();\n\treturn (t) => _(t, e);\n}, y = (e) => {\n\tlet t = e.pageSpreadLeft === !0;\n\tif (t !== (e.pageSpreadRight === !0)) return t ? \"left\" : \"right\";\n}, b = (e, t, n) => {\n\tif (Object.is(e, t)) return !0;\n\tif (typeof e != \"object\" || !e || typeof t != \"object\" || !t) return !1;\n\tlet r = Object.keys(e), i = Object.keys(t);\n\tif (r.length !== i.length) return !1;\n\tlet a = n?.customEqual ?? Object.is, o = e, s = t;\n\tfor (let e of r) if (!Object.hasOwn(s, e) || !a(o[e], s[e])) return !1;\n\treturn !0;\n}, x = (e, t) => e.reduce((e, n) => {\n\tlet r = t(n);\n\treturn e[r] || (e[r] = []), e[r].push(n), e;\n}, {});\nfunction S(e, t) {\n\tlet n = { ...e };\n\tfor (let r in t) if (Object.hasOwn(t, r)) {\n\t\tlet i = t[r];\n\t\t(i !== void 0 || !(r in e)) && (n[r] = i);\n\t}\n\treturn n;\n}\n//#endregion\n//#region src/report.ts\nfunction C() {\n\tlet e = globalThis.__PROSE_READER_DEBUG;\n\treturn e === !0 || e === \"true\";\n}\nvar w = (e, t) => typeof e == \"boolean\" ? {\n\tenabled: e,\n\toptions: t\n} : {\n\tenabled: e?.enabled,\n\toptions: e ?? t\n}, T = (e) => e.at(-1)?.color, E = (e) => {\n\tif (!e.length) return;\n\tif (!e.some((e) => e.color)) return [e.map((e) => e.label).join(\" \")];\n\tlet t = \"\", n = [];\n\tfor (let r of e) t += `%c${t ? ` ${r.label}` : r.label}`, n.push(r.color ? `color: ${r.color}` : \"\");\n\treturn [t, ...n];\n}, D = (e = [], t = C()) => {\n\tlet n = t, r = {\n\t\tenable: (e) => {\n\t\t\ta(e);\n\t\t},\n\t\tnamespace: (t, r, i) => {\n\t\t\tlet a = w(r, i), o = a.options?.color ?? T(e);\n\t\t\treturn D([...e, {\n\t\t\t\tlabel: `[${t}]`,\n\t\t\t\tcolor: o\n\t\t\t}], a.enabled ?? n);\n\t\t},\n\t\tisEnabled: () => n,\n\t\tdebug: () => {},\n\t\tinfo: () => {},\n\t\tlog: () => {},\n\t\tgroupCollapsed: () => {},\n\t\tgroupEnd: () => {},\n\t\tgetGroupArgs: (t) => {\n\t\t\tlet n = E(e);\n\t\t\tif (!n) return [t];\n\t\t\tlet [r, ...i] = n;\n\t\t\treturn [`${r} ${t}`, ...i];\n\t\t},\n\t\twarn: () => {},\n\t\terror: () => {}\n\t}, i = (t) => {\n\t\tif (!t) {\n\t\t\tr.debug = () => {}, r.info = () => {}, r.log = () => {}, r.groupCollapsed = () => {}, r.groupEnd = () => {}, r.warn = () => {}, r.error = () => {};\n\t\t\treturn;\n\t\t}\n\t\tlet n = E(e) ?? [];\n\t\tr.debug = Function.prototype.bind.call(console.debug, console, ...n), r.info = Function.prototype.bind.call(console.info, console, ...n), r.log = Function.prototype.bind.call(console.log, console, ...n), r.groupCollapsed = Function.prototype.bind.call(console.groupCollapsed, console), r.groupEnd = Function.prototype.bind.call(console.groupEnd, console), r.warn = Function.prototype.bind.call(console.warn, console, ...n), r.error = Function.prototype.bind.call(console.error, console, ...n);\n\t}, a = (e) => {\n\t\tn !== e && (n = e, i(n));\n\t};\n\treturn i(n), r;\n}, O = D(), k = \"prose-reader-resource-error\", A = (e, t) => {\n\tlet n = e.split(/(\\d+)/), r = t.split(/(\\d+)/);\n\tfor (let e = 0, t = n.length; e < t; e++) if (n[e] !== r[e]) return n[e]?.match(/\\d/) ? +(n[e] || \"\") - (r[e] || \"\") : (n[e] || \"\").localeCompare(r[e] || \"\");\n\treturn 1;\n}, j = (e) => e.endsWith(\"/\") ? e.slice(0, -1) : e, M = (e) => {\n\tlet t = j(e);\n\treturn t.substring(t.lastIndexOf(\"/\") + 1) || t;\n}, N = (e) => {\n\tlet t = e.lastIndexOf(\"/\");\n\treturn t >= 0 ? e.substring(0, t) : \"\";\n}, P = (e) => e.replaceAll(\"&\", \"&\").replaceAll(\"\\\"\", \""\").replaceAll(\"'\", \"'\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\");\n//#endregion\nexport { k as PROSE_READER_RESOURCE_ERROR_INJECTED_META_NAME, O as Report, e as arrayEqual, _ as createUniqueXmlSafeId, g as createXmlSafeId, v as createXmlSafeIdFactory, a as detectMimeTypeFromName, P as escapeXmlAttributeValue, y as getItemSpreadPosition, i as getParentPath, N as getUriBasePath, M as getUriBasename, t as getUrlExtension, x as groupBy, s as isMediaContentMimeType, b as isShallowEqual, o as isXmlBasedMimeType, c as parseContentType, j as removeTrailingSlash, S as shallowMergeIfDefined, A as sortByTitleComparator, r as urlJoin };\n\n//# sourceMappingURL=index.js.map","{\n \"name\": \"@prose-reader/enhancer-search\",\n \"version\": \"1.373.0\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"/dist\"\n ],\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"scripts\": {\n \"start\": \"vite build --watch --mode development\",\n \"build\": \"tsc && vite build\",\n \"test\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@prose-reader/core\": \"^1.373.0\"\n },\n \"peerDependencies\": {\n \"rxjs\": \"*\"\n },\n \"gitHead\": \"4601e14dcacf50b2295cb343582a7ef2c7e1eedc\"\n}\n","import { Report } from \"@prose-reader/shared\"\nimport { name } from \"../package.json\"\n\nconst IS_DEBUG_ENABLED = true\n\nexport const report = Report.namespace(name, IS_DEBUG_ENABLED)\n","import type { Reader, SpineItem } from \"@prose-reader/core\"\nimport { type Observable, of } from \"rxjs\"\nimport type { ResultItem } from \"./types\"\n\nexport type SearchResult = ResultItem[]\n\n/**\n * Walk the subtree accumulating ranges for every match of `regexp`.\n *\n * A full-book search runs this over the rendered document of *every* spine\n * item, so the text-node loop below is the hot path (thousands of text nodes\n * per large chapter). Two things are hoisted out of it to keep the work\n * proportional to the number of matches rather than the number of nodes:\n * - the search regexp is compiled once by the caller and reused across every\n * node (only its `lastIndex` is reset), instead of recompiling per text node,\n * - matches are pushed into a single shared array instead of allocating a new\n * array at each node and spreading child results upward.\n */\nconst collectMatchingRanges = (\n node: Node,\n regexp: RegExp,\n matchLength: number,\n rangeList: Range[],\n) => {\n if (node.nodeName === `head`) return\n\n const nodeList = node.childNodes\n\n for (let i = 0; i < nodeList.length; i++) {\n const subNode = nodeList[i]\n\n if (!subNode) {\n continue\n }\n\n if (subNode.hasChildNodes()) {\n collectMatchingRanges(subNode, regexp, matchLength, rangeList)\n }\n\n if (subNode.nodeType === 3) {\n const content = (subNode as Text).data.toLowerCase()\n if (content) {\n let match: RegExpExecArray | null = null\n regexp.lastIndex = 0\n\n // biome-ignore lint/suspicious/noAssignInExpressions: TODO\n while ((match = regexp.exec(content)) !== null) {\n if (match.index >= 0 && subNode.ownerDocument) {\n const range = subNode.ownerDocument.createRange()\n range.setStart(subNode, match.index)\n range.setEnd(subNode, match.index + matchLength)\n\n rangeList.push(range)\n }\n }\n }\n }\n }\n}\n\nconst searchNodeContainingText = (node: Node, text: string) => {\n const rangeList: Range[] = []\n\n collectMatchingRanges(node, RegExp(`(${text})`, `gi`), text.length, rangeList)\n\n return rangeList\n}\n\nexport const searchInDocument = (\n reader: Reader,\n item: SpineItem,\n doc: Document,\n text: string,\n): Observable<SearchResult> => {\n const ranges = searchNodeContainingText(doc, text)\n\n const newResults = ranges.map((range) => {\n const cfi = reader.cfi.generateCfiFromRange(range, item.item)\n\n return {\n cfi,\n } satisfies ResultItem\n })\n\n return of(newResults)\n}\n","import { deferIdle, type Reader } from \"@prose-reader/core\"\nimport { defer, forkJoin, of } from \"rxjs\"\nimport { catchError, finalize, map, switchMap } from \"rxjs/operators\"\nimport { report } from \"./report\"\nimport type { SearchResult } from \"./search\"\nimport { searchInDocument } from \"./search\"\nimport type { ResultItem, SearchEnhancerAPI } from \"./types\"\n\nexport type { ResultItem, SearchEnhancerAPI, SearchResult }\n\n/**\n * Contract of search enhancer.\n *\n * - At best a result match should be navigable. It means the search needs to\n * be done on a rendered document. This is because rendering can differ from the original\n * item resource. A resource can be something non digestible and very specific (.pdf). The search\n * enhancer is agnostic and can only search into documents.\n */\nexport const searchEnhancer =\n <InheritOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (options: InheritOptions): InheritOutput & SearchEnhancerAPI => {\n const reader = next(options)\n\n const searchForItem = (index: number, text: string) => {\n const item = reader.spineItemsManager.get(index)\n\n if (!item) {\n return of([])\n }\n\n return deferIdle(() => reader.renderHeadless(index)).pipe(\n switchMap((result) => {\n const { doc, release } = result || {}\n\n if (!doc) return of([])\n\n return deferIdle(() =>\n searchInDocument(reader, item, doc, text),\n ).pipe(\n finalize(() => {\n release?.()\n }),\n catchError((e) => {\n report.error(e)\n\n return of([])\n }),\n )\n }),\n )\n }\n\n const search = (text: string) =>\n defer(() => {\n if (text === ``) {\n return of([])\n }\n\n const searches$ =\n reader.context.manifest?.spineItems.map((_, index) =>\n searchForItem(index, text),\n ) || []\n\n return forkJoin([...searches$, of([])])\n }).pipe(\n map((results) => {\n const flattenedResults = results.flat()\n\n report.debug(\"results\", flattenedResults)\n\n return flattenedResults\n }),\n )\n\n return {\n ...reader,\n __PROSE_READER_ENHANCER_SEARCH: true,\n search: {\n search,\n },\n }\n }\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -74,7 +74,10 @@ var l = (e, t) => typeof e == "boolean" ? {
|
|
|
74
74
|
}, h = (e, t) => {
|
|
75
75
|
let n = [];
|
|
76
76
|
return m(e, RegExp(`(${t})`, "gi"), t.length, n), n;
|
|
77
|
-
}, g = (e, t, n, i) =>
|
|
77
|
+
}, g = (e, t, n, i) => {
|
|
78
|
+
let a = h(n, i).map((n) => ({ cfi: e.cfi.generateCfiFromRange(n, t.item) }));
|
|
79
|
+
return r(a);
|
|
80
|
+
}, _ = (c) => (l) => {
|
|
78
81
|
let u = c(l), d = (t, n) => {
|
|
79
82
|
let o = u.spineItemsManager.get(t);
|
|
80
83
|
return o ? e(() => u.renderHeadless(t)).pipe(s((t) => {
|
|
@@ -83,7 +86,11 @@ var l = (e, t) => typeof e == "boolean" ? {
|
|
|
83
86
|
c?.();
|
|
84
87
|
}), i((e) => (p.error(e), r([])))) : r([]);
|
|
85
88
|
})) : r([]);
|
|
86
|
-
}, f = (e) => t(() =>
|
|
89
|
+
}, f = (e) => t(() => {
|
|
90
|
+
if (e === "") return r([]);
|
|
91
|
+
let t = u.context.manifest?.spineItems.map((t, n) => d(n, e)) || [];
|
|
92
|
+
return n([...t, r([])]);
|
|
93
|
+
}).pipe(o((e) => {
|
|
87
94
|
let t = e.flat();
|
|
88
95
|
return p.debug("results", t), t;
|
|
89
96
|
}));
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../shared/dist/index.js","../package.json","../src/report.ts","../src/search.ts","../src/index.ts"],"sourcesContent":["//#region src/array.ts\nvar e = (e, t) => e === t || e.length === t.length && e.every((e, n) => e === t[n]), t = (e) => e.split(/[#?]/)[0]?.split(\".\").pop()?.trim() || \"\";\nfunction n(e) {\n\tlet t = [];\n\tif (e.length === 0) return \"\";\n\tif (typeof e[0] != \"string\") throw TypeError(`Url must be a string. Received ${e[0]}`);\n\te[0].match(/^[^/:]+:\\/*$/) && e.length > 1 && (e[0] = e.shift() + e[0]), e[0].match(/^file:\\/\\/\\//) ? e[0] = e[0].replace(/^([^/:]+):\\/*/, \"$1:///\") : e[0] = e[0].replace(/^([^/:]+):\\/*/, \"$1://\");\n\tfor (let n = 0; n < e.length; n++) {\n\t\tlet r = e[n];\n\t\tif (typeof r != \"string\") throw TypeError(`Url must be a string. Received ${r}`);\n\t\tr !== \"\" && (n > 0 && (r = r.replace(/^[/]+/, \"\")), r = n < e.length - 1 ? r.replace(/[/]+$/, \"\") : r.replace(/[/]+$/, \"/\"), t.push(r));\n\t}\n\tlet n = t.join(\"/\");\n\tn = n.replace(/\\/(\\?|&|#[^!])/g, \"$1\");\n\tlet r = n.split(\"?\");\n\treturn n = r.shift() + (r.length > 0 ? \"?\" : \"\") + r.join(\"&\"), n;\n}\nfunction r(...e) {\n\treturn n(Array.from(Array.isArray(e[0]) ? e[0] : e));\n}\nfunction i(e) {\n\tlet t = e.split(\"/\");\n\treturn t.pop(), t.join(\"/\");\n}\n//#endregion\n//#region src/contentType.ts\nvar a = (e) => {\n\tswitch (t(e).toLowerCase()) {\n\t\tcase \"png\": return \"image/png\";\n\t\tcase \"jpg\": return \"image/jpg\";\n\t\tcase \"jpeg\": return \"image/jpeg\";\n\t\tcase \"gif\": return \"image/gif\";\n\t\tcase \"webp\": return \"image/webp\";\n\t\tcase \"avif\": return \"image/avif\";\n\t\tcase \"bmp\": return \"image/bmp\";\n\t\tcase \"tif\":\n\t\tcase \"tiff\": return \"image/tiff\";\n\t\tcase \"svg\": return \"image/svg+xml\";\n\t\tcase \"txt\": return \"text/plain\";\n\t\tcase \"xhtml\": return \"application/xhtml+xml\";\n\t\tcase \"mp3\": return \"audio/mpeg\";\n\t\tcase \"m4a\":\n\t\tcase \"m4b\": return \"audio/mp4\";\n\t\tcase \"aac\": return \"audio/aac\";\n\t\tcase \"ogg\":\n\t\tcase \"oga\": return \"audio/ogg\";\n\t\tcase \"wav\": return \"audio/wav\";\n\t\tcase \"flac\": return \"audio/flac\";\n\t\tcase \"opus\": return \"audio/opus\";\n\t}\n}, o = ({ mimeType: e, uri: t }) => (e ?? a(t ?? \"\"))?.startsWith(\"application/xhtml+xml\"), s = (e) => e.startsWith(\"image/\") || e.startsWith(\"audio/\") || e.startsWith(\"video/\"), c = (e) => {\n\tif (!e.length) return;\n\tlet t = e.indexOf(\";\");\n\treturn t >= 0 ? e.substring(0, t) : e;\n}, l = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/, u = /^[A-Za-z0-9_]/, d = /^xml/i, f = /[^A-Za-z0-9_.-]+/g, p = \"_\", m = (e) => e.replace(/^_+|_+$/g, \"\"), h = (e) => m(e.trim().replaceAll(\"/\", \"_\").replace(f, \"_\")), g = (e) => {\n\tif (l.test(e) && !d.test(e)) return e;\n\tlet t = h(e), n = t && !d.test(t) ? t : `${p}${t}`;\n\treturn u.test(n) ? n : `${p}${n}`;\n}, _ = (e, t) => {\n\tlet n = g(e);\n\tif (!t.has(n)) return t.add(n), n;\n\tlet r = 2, i = `${n}-${r}`;\n\tfor (; t.has(i);) r += 1, i = `${n}-${r}`;\n\treturn t.add(i), i;\n}, v = () => {\n\tlet e = /* @__PURE__ */ new Set();\n\treturn (t) => _(t, e);\n}, y = (e) => {\n\tlet t = e.pageSpreadLeft === !0;\n\tif (t !== (e.pageSpreadRight === !0)) return t ? \"left\" : \"right\";\n}, b = (e, t, n) => {\n\tif (Object.is(e, t)) return !0;\n\tif (typeof e != \"object\" || !e || typeof t != \"object\" || !t) return !1;\n\tlet r = Object.keys(e), i = Object.keys(t);\n\tif (r.length !== i.length) return !1;\n\tlet a = n?.customEqual ?? Object.is, o = e, s = t;\n\tfor (let e of r) if (!Object.hasOwn(s, e) || !a(o[e], s[e])) return !1;\n\treturn !0;\n}, x = (e, t) => e.reduce((e, n) => {\n\tlet r = t(n);\n\treturn e[r] || (e[r] = []), e[r].push(n), e;\n}, {});\nfunction S(e, t) {\n\tlet n = { ...e };\n\tfor (let r in t) if (Object.hasOwn(t, r)) {\n\t\tlet i = t[r];\n\t\t(i !== void 0 || !(r in e)) && (n[r] = i);\n\t}\n\treturn n;\n}\n//#endregion\n//#region src/report.ts\nfunction C() {\n\tlet e = globalThis.__PROSE_READER_DEBUG;\n\treturn e === !0 || e === \"true\";\n}\nvar w = (e, t) => typeof e == \"boolean\" ? {\n\tenabled: e,\n\toptions: t\n} : {\n\tenabled: e?.enabled,\n\toptions: e ?? t\n}, T = (e) => e.at(-1)?.color, E = (e) => {\n\tif (!e.length) return;\n\tif (!e.some((e) => e.color)) return [e.map((e) => e.label).join(\" \")];\n\tlet t = \"\", n = [];\n\tfor (let r of e) t += `%c${t ? ` ${r.label}` : r.label}`, n.push(r.color ? `color: ${r.color}` : \"\");\n\treturn [t, ...n];\n}, D = (e = [], t = C()) => {\n\tlet n = t, r = {\n\t\tenable: (e) => {\n\t\t\ta(e);\n\t\t},\n\t\tnamespace: (t, r, i) => {\n\t\t\tlet a = w(r, i), o = a.options?.color ?? T(e);\n\t\t\treturn D([...e, {\n\t\t\t\tlabel: `[${t}]`,\n\t\t\t\tcolor: o\n\t\t\t}], a.enabled ?? n);\n\t\t},\n\t\tisEnabled: () => n,\n\t\tdebug: () => {},\n\t\tinfo: () => {},\n\t\tlog: () => {},\n\t\tgroupCollapsed: () => {},\n\t\tgroupEnd: () => {},\n\t\tgetGroupArgs: (t) => {\n\t\t\tlet n = E(e);\n\t\t\tif (!n) return [t];\n\t\t\tlet [r, ...i] = n;\n\t\t\treturn [`${r} ${t}`, ...i];\n\t\t},\n\t\twarn: () => {},\n\t\terror: () => {}\n\t}, i = (t) => {\n\t\tif (!t) {\n\t\t\tr.debug = () => {}, r.info = () => {}, r.log = () => {}, r.groupCollapsed = () => {}, r.groupEnd = () => {}, r.warn = () => {}, r.error = () => {};\n\t\t\treturn;\n\t\t}\n\t\tlet n = E(e) ?? [];\n\t\tr.debug = Function.prototype.bind.call(console.debug, console, ...n), r.info = Function.prototype.bind.call(console.info, console, ...n), r.log = Function.prototype.bind.call(console.log, console, ...n), r.groupCollapsed = Function.prototype.bind.call(console.groupCollapsed, console), r.groupEnd = Function.prototype.bind.call(console.groupEnd, console), r.warn = Function.prototype.bind.call(console.warn, console, ...n), r.error = Function.prototype.bind.call(console.error, console, ...n);\n\t}, a = (e) => {\n\t\tn !== e && (n = e, i(n));\n\t};\n\treturn i(n), r;\n}, O = D(), k = \"prose-reader-resource-error\", A = (e, t) => {\n\tlet n = e.split(/(\\d+)/), r = t.split(/(\\d+)/);\n\tfor (let e = 0, t = n.length; e < t; e++) if (n[e] !== r[e]) return n[e]?.match(/\\d/) ? (n[e] || \"\") - +(r[e] || \"\") : (n[e] || \"\").localeCompare(r[e] || \"\");\n\treturn 1;\n}, j = (e) => e.endsWith(\"/\") ? e.slice(0, -1) : e, M = (e) => {\n\tlet t = j(e);\n\treturn t.substring(t.lastIndexOf(\"/\") + 1) || t;\n}, N = (e) => {\n\tlet t = e.lastIndexOf(\"/\");\n\treturn t >= 0 ? e.substring(0, t) : \"\";\n}, P = (e) => e.replaceAll(\"&\", \"&\").replaceAll(\"\\\"\", \""\").replaceAll(\"'\", \"'\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\");\n//#endregion\nexport { k as PROSE_READER_RESOURCE_ERROR_INJECTED_META_NAME, O as Report, e as arrayEqual, _ as createUniqueXmlSafeId, g as createXmlSafeId, v as createXmlSafeIdFactory, a as detectMimeTypeFromName, P as escapeXmlAttributeValue, y as getItemSpreadPosition, i as getParentPath, N as getUriBasePath, M as getUriBasename, t as getUrlExtension, x as groupBy, s as isMediaContentMimeType, b as isShallowEqual, o as isXmlBasedMimeType, c as parseContentType, j as removeTrailingSlash, S as shallowMergeIfDefined, A as sortByTitleComparator, r as urlJoin };\n\n//# sourceMappingURL=index.js.map","{\n \"name\": \"@prose-reader/enhancer-search\",\n \"version\": \"1.371.0\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"/dist\"\n ],\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"scripts\": {\n \"start\": \"vite build --watch --mode development\",\n \"build\": \"tsc && vite build\",\n \"test\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@prose-reader/core\": \"^1.371.0\"\n },\n \"peerDependencies\": {\n \"rxjs\": \"*\"\n },\n \"gitHead\": \"4601e14dcacf50b2295cb343582a7ef2c7e1eedc\"\n}\n","import { Report } from \"@prose-reader/shared\"\nimport { name } from \"../package.json\"\n\nconst IS_DEBUG_ENABLED = true\n\nexport const report = Report.namespace(name, IS_DEBUG_ENABLED)\n","import type { Reader, SpineItem } from \"@prose-reader/core\"\nimport { type Observable, of } from \"rxjs\"\nimport type { ResultItem } from \"./types\"\n\nexport type SearchResult = ResultItem[]\n\n/**\n * Walk the subtree accumulating ranges for every match of `regexp`.\n *\n * A full-book search runs this over the rendered document of *every* spine\n * item, so the text-node loop below is the hot path (thousands of text nodes\n * per large chapter). Two things are hoisted out of it to keep the work\n * proportional to the number of matches rather than the number of nodes:\n * - the search regexp is compiled once by the caller and reused across every\n * node (only its `lastIndex` is reset), instead of recompiling per text node,\n * - matches are pushed into a single shared array instead of allocating a new\n * array at each node and spreading child results upward.\n */\nconst collectMatchingRanges = (\n node: Node,\n regexp: RegExp,\n matchLength: number,\n rangeList: Range[],\n) => {\n if (node.nodeName === `head`) return\n\n const nodeList = node.childNodes\n\n for (let i = 0; i < nodeList.length; i++) {\n const subNode = nodeList[i]\n\n if (!subNode) {\n continue\n }\n\n if (subNode.hasChildNodes()) {\n collectMatchingRanges(subNode, regexp, matchLength, rangeList)\n }\n\n if (subNode.nodeType === 3) {\n const content = (subNode as Text).data.toLowerCase()\n if (content) {\n let match: RegExpExecArray | null = null\n regexp.lastIndex = 0\n\n // biome-ignore lint/suspicious/noAssignInExpressions: TODO\n while ((match = regexp.exec(content)) !== null) {\n if (match.index >= 0 && subNode.ownerDocument) {\n const range = subNode.ownerDocument.createRange()\n range.setStart(subNode, match.index)\n range.setEnd(subNode, match.index + matchLength)\n\n rangeList.push(range)\n }\n }\n }\n }\n }\n}\n\nconst searchNodeContainingText = (node: Node, text: string) => {\n const rangeList: Range[] = []\n\n collectMatchingRanges(node, RegExp(`(${text})`, `gi`), text.length, rangeList)\n\n return rangeList\n}\n\nexport const searchInDocument = (\n reader: Reader,\n item: SpineItem,\n doc: Document,\n text: string,\n): Observable<SearchResult> => {\n const ranges = searchNodeContainingText(doc, text)\n\n const newResults = ranges.map((range) => {\n const cfi = reader.cfi.generateCfiFromRange(range, item.item)\n\n return {\n cfi,\n } satisfies ResultItem\n })\n\n return of(newResults)\n}\n","import { deferIdle, type Reader } from \"@prose-reader/core\"\nimport { defer, forkJoin, of } from \"rxjs\"\nimport { catchError, finalize, map, switchMap } from \"rxjs/operators\"\nimport { report } from \"./report\"\nimport type { SearchResult } from \"./search\"\nimport { searchInDocument } from \"./search\"\nimport type { ResultItem, SearchEnhancerAPI } from \"./types\"\n\nexport type { ResultItem, SearchEnhancerAPI, SearchResult }\n\n/**\n * Contract of search enhancer.\n *\n * - At best a result match should be navigable. It means the search needs to\n * be done on a rendered document. This is because rendering can differ from the original\n * item resource. A resource can be something non digestible and very specific (.pdf). The search\n * enhancer is agnostic and can only search into documents.\n */\nexport const searchEnhancer =\n <InheritOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (options: InheritOptions): InheritOutput & SearchEnhancerAPI => {\n const reader = next(options)\n\n const searchForItem = (index: number, text: string) => {\n const item = reader.spineItemsManager.get(index)\n\n if (!item) {\n return of([])\n }\n\n return deferIdle(() => reader.renderHeadless(index)).pipe(\n switchMap((result) => {\n const { doc, release } = result || {}\n\n if (!doc) return of([])\n\n return deferIdle(() =>\n searchInDocument(reader, item, doc, text),\n ).pipe(\n finalize(() => {\n release?.()\n }),\n catchError((e) => {\n report.error(e)\n\n return of([])\n }),\n )\n }),\n )\n }\n\n const search = (text: string) =>\n defer(() => {\n if (text === ``) {\n return of([])\n }\n\n const searches$ =\n reader.context.manifest?.spineItems.map((_, index) =>\n searchForItem(index, text),\n ) || []\n\n return forkJoin([...searches$, of([])])\n }).pipe(\n map((results) => {\n const flattenedResults = results.flat()\n\n report.debug(\"results\", flattenedResults)\n\n return flattenedResults\n }),\n )\n\n return {\n ...reader,\n __PROSE_READER_ENHANCER_SEARCH: true,\n search: {\n search,\n },\n }\n }\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../shared/dist/index.js","../package.json","../src/report.ts","../src/search.ts","../src/index.ts"],"sourcesContent":["//#region src/array.ts\nvar e = (e, t) => e === t || e.length === t.length && e.every((e, n) => e === t[n]), t = (e) => e.split(/[#?]/)[0]?.split(\".\").pop()?.trim() || \"\";\nfunction n(e) {\n\tlet t = [];\n\tif (e.length === 0) return \"\";\n\tif (typeof e[0] != \"string\") throw TypeError(`Url must be a string. Received ${e[0]}`);\n\te[0].match(/^[^/:]+:\\/*$/) && e.length > 1 && (e[0] = e.shift() + e[0]), e[0] = e[0].match(/^file:\\/\\/\\//) ? e[0].replace(/^([^/:]+):\\/*/, \"$1:///\") : e[0].replace(/^([^/:]+):\\/*/, \"$1://\");\n\tfor (let n = 0; n < e.length; n++) {\n\t\tlet r = e[n];\n\t\tif (typeof r != \"string\") throw TypeError(`Url must be a string. Received ${r}`);\n\t\tr !== \"\" && (n > 0 && (r = r.replace(/^[/]+/, \"\")), r = n < e.length - 1 ? r.replace(/[/]+$/, \"\") : r.replace(/[/]+$/, \"/\"), t.push(r));\n\t}\n\tlet n = t.join(\"/\");\n\tn = n.replace(/\\/(\\?|&|#[^!])/g, \"$1\");\n\tlet r = n.split(\"?\");\n\treturn n = r.shift() + (r.length > 0 ? \"?\" : \"\") + r.join(\"&\"), n;\n}\nfunction r(...e) {\n\treturn n(Array.from(Array.isArray(e[0]) ? e[0] : e));\n}\nfunction i(e) {\n\tlet t = e.split(\"/\");\n\treturn t.pop(), t.join(\"/\");\n}\n//#endregion\n//#region src/contentType.ts\nvar a = (e) => {\n\tswitch (t(e).toLowerCase()) {\n\t\tcase \"png\": return \"image/png\";\n\t\tcase \"jpg\": return \"image/jpg\";\n\t\tcase \"jpeg\": return \"image/jpeg\";\n\t\tcase \"gif\": return \"image/gif\";\n\t\tcase \"webp\": return \"image/webp\";\n\t\tcase \"avif\": return \"image/avif\";\n\t\tcase \"bmp\": return \"image/bmp\";\n\t\tcase \"tif\":\n\t\tcase \"tiff\": return \"image/tiff\";\n\t\tcase \"svg\": return \"image/svg+xml\";\n\t\tcase \"txt\": return \"text/plain\";\n\t\tcase \"xhtml\": return \"application/xhtml+xml\";\n\t\tcase \"mp3\": return \"audio/mpeg\";\n\t\tcase \"m4a\":\n\t\tcase \"m4b\": return \"audio/mp4\";\n\t\tcase \"aac\": return \"audio/aac\";\n\t\tcase \"ogg\":\n\t\tcase \"oga\": return \"audio/ogg\";\n\t\tcase \"wav\": return \"audio/wav\";\n\t\tcase \"flac\": return \"audio/flac\";\n\t\tcase \"opus\": return \"audio/opus\";\n\t}\n}, o = ({ mimeType: e, uri: t }) => (e ?? a(t ?? \"\"))?.startsWith(\"application/xhtml+xml\"), s = (e) => e.startsWith(\"image/\") || e.startsWith(\"audio/\") || e.startsWith(\"video/\"), c = (e) => {\n\tif (!e.length) return;\n\tlet t = e.indexOf(\";\");\n\treturn t >= 0 ? e.substring(0, t) : e;\n}, l = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/, u = /^[A-Za-z0-9_]/, d = /^xml/i, f = /[^A-Za-z0-9_.-]+/g, p = \"_\", m = (e) => e.replace(/^_+|_+$/g, \"\"), h = (e) => m(e.trim().replaceAll(\"/\", \"_\").replace(f, \"_\")), g = (e) => {\n\tif (l.test(e) && !d.test(e)) return e;\n\tlet t = h(e), n = t && !d.test(t) ? t : `${p}${t}`;\n\treturn u.test(n) ? n : `${p}${n}`;\n}, _ = (e, t) => {\n\tlet n = g(e);\n\tif (!t.has(n)) return t.add(n), n;\n\tlet r = 2, i = `${n}-${r}`;\n\tfor (; t.has(i);) r += 1, i = `${n}-${r}`;\n\treturn t.add(i), i;\n}, v = () => {\n\tlet e = /* @__PURE__ */ new Set();\n\treturn (t) => _(t, e);\n}, y = (e) => {\n\tlet t = e.pageSpreadLeft === !0;\n\tif (t !== (e.pageSpreadRight === !0)) return t ? \"left\" : \"right\";\n}, b = (e, t, n) => {\n\tif (Object.is(e, t)) return !0;\n\tif (typeof e != \"object\" || !e || typeof t != \"object\" || !t) return !1;\n\tlet r = Object.keys(e), i = Object.keys(t);\n\tif (r.length !== i.length) return !1;\n\tlet a = n?.customEqual ?? Object.is, o = e, s = t;\n\tfor (let e of r) if (!Object.hasOwn(s, e) || !a(o[e], s[e])) return !1;\n\treturn !0;\n}, x = (e, t) => e.reduce((e, n) => {\n\tlet r = t(n);\n\treturn e[r] || (e[r] = []), e[r].push(n), e;\n}, {});\nfunction S(e, t) {\n\tlet n = { ...e };\n\tfor (let r in t) if (Object.hasOwn(t, r)) {\n\t\tlet i = t[r];\n\t\t(i !== void 0 || !(r in e)) && (n[r] = i);\n\t}\n\treturn n;\n}\n//#endregion\n//#region src/report.ts\nfunction C() {\n\tlet e = globalThis.__PROSE_READER_DEBUG;\n\treturn e === !0 || e === \"true\";\n}\nvar w = (e, t) => typeof e == \"boolean\" ? {\n\tenabled: e,\n\toptions: t\n} : {\n\tenabled: e?.enabled,\n\toptions: e ?? t\n}, T = (e) => e.at(-1)?.color, E = (e) => {\n\tif (!e.length) return;\n\tif (!e.some((e) => e.color)) return [e.map((e) => e.label).join(\" \")];\n\tlet t = \"\", n = [];\n\tfor (let r of e) t += `%c${t ? ` ${r.label}` : r.label}`, n.push(r.color ? `color: ${r.color}` : \"\");\n\treturn [t, ...n];\n}, D = (e = [], t = C()) => {\n\tlet n = t, r = {\n\t\tenable: (e) => {\n\t\t\ta(e);\n\t\t},\n\t\tnamespace: (t, r, i) => {\n\t\t\tlet a = w(r, i), o = a.options?.color ?? T(e);\n\t\t\treturn D([...e, {\n\t\t\t\tlabel: `[${t}]`,\n\t\t\t\tcolor: o\n\t\t\t}], a.enabled ?? n);\n\t\t},\n\t\tisEnabled: () => n,\n\t\tdebug: () => {},\n\t\tinfo: () => {},\n\t\tlog: () => {},\n\t\tgroupCollapsed: () => {},\n\t\tgroupEnd: () => {},\n\t\tgetGroupArgs: (t) => {\n\t\t\tlet n = E(e);\n\t\t\tif (!n) return [t];\n\t\t\tlet [r, ...i] = n;\n\t\t\treturn [`${r} ${t}`, ...i];\n\t\t},\n\t\twarn: () => {},\n\t\terror: () => {}\n\t}, i = (t) => {\n\t\tif (!t) {\n\t\t\tr.debug = () => {}, r.info = () => {}, r.log = () => {}, r.groupCollapsed = () => {}, r.groupEnd = () => {}, r.warn = () => {}, r.error = () => {};\n\t\t\treturn;\n\t\t}\n\t\tlet n = E(e) ?? [];\n\t\tr.debug = Function.prototype.bind.call(console.debug, console, ...n), r.info = Function.prototype.bind.call(console.info, console, ...n), r.log = Function.prototype.bind.call(console.log, console, ...n), r.groupCollapsed = Function.prototype.bind.call(console.groupCollapsed, console), r.groupEnd = Function.prototype.bind.call(console.groupEnd, console), r.warn = Function.prototype.bind.call(console.warn, console, ...n), r.error = Function.prototype.bind.call(console.error, console, ...n);\n\t}, a = (e) => {\n\t\tn !== e && (n = e, i(n));\n\t};\n\treturn i(n), r;\n}, O = D(), k = \"prose-reader-resource-error\", A = (e, t) => {\n\tlet n = e.split(/(\\d+)/), r = t.split(/(\\d+)/);\n\tfor (let e = 0, t = n.length; e < t; e++) if (n[e] !== r[e]) return n[e]?.match(/\\d/) ? +(n[e] || \"\") - (r[e] || \"\") : (n[e] || \"\").localeCompare(r[e] || \"\");\n\treturn 1;\n}, j = (e) => e.endsWith(\"/\") ? e.slice(0, -1) : e, M = (e) => {\n\tlet t = j(e);\n\treturn t.substring(t.lastIndexOf(\"/\") + 1) || t;\n}, N = (e) => {\n\tlet t = e.lastIndexOf(\"/\");\n\treturn t >= 0 ? e.substring(0, t) : \"\";\n}, P = (e) => e.replaceAll(\"&\", \"&\").replaceAll(\"\\\"\", \""\").replaceAll(\"'\", \"'\").replaceAll(\"<\", \"<\").replaceAll(\">\", \">\");\n//#endregion\nexport { k as PROSE_READER_RESOURCE_ERROR_INJECTED_META_NAME, O as Report, e as arrayEqual, _ as createUniqueXmlSafeId, g as createXmlSafeId, v as createXmlSafeIdFactory, a as detectMimeTypeFromName, P as escapeXmlAttributeValue, y as getItemSpreadPosition, i as getParentPath, N as getUriBasePath, M as getUriBasename, t as getUrlExtension, x as groupBy, s as isMediaContentMimeType, b as isShallowEqual, o as isXmlBasedMimeType, c as parseContentType, j as removeTrailingSlash, S as shallowMergeIfDefined, A as sortByTitleComparator, r as urlJoin };\n\n//# sourceMappingURL=index.js.map","{\n \"name\": \"@prose-reader/enhancer-search\",\n \"version\": \"1.373.0\",\n \"type\": \"module\",\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"files\": [\n \"/dist\"\n ],\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"exports\": {\n \".\": {\n \"import\": \"./dist/index.js\",\n \"require\": \"./dist/index.cjs\"\n }\n },\n \"scripts\": {\n \"start\": \"vite build --watch --mode development\",\n \"build\": \"tsc && vite build\",\n \"test\": \"vitest run --coverage\"\n },\n \"dependencies\": {\n \"@prose-reader/core\": \"^1.373.0\"\n },\n \"peerDependencies\": {\n \"rxjs\": \"*\"\n },\n \"gitHead\": \"4601e14dcacf50b2295cb343582a7ef2c7e1eedc\"\n}\n","import { Report } from \"@prose-reader/shared\"\nimport { name } from \"../package.json\"\n\nconst IS_DEBUG_ENABLED = true\n\nexport const report = Report.namespace(name, IS_DEBUG_ENABLED)\n","import type { Reader, SpineItem } from \"@prose-reader/core\"\nimport { type Observable, of } from \"rxjs\"\nimport type { ResultItem } from \"./types\"\n\nexport type SearchResult = ResultItem[]\n\n/**\n * Walk the subtree accumulating ranges for every match of `regexp`.\n *\n * A full-book search runs this over the rendered document of *every* spine\n * item, so the text-node loop below is the hot path (thousands of text nodes\n * per large chapter). Two things are hoisted out of it to keep the work\n * proportional to the number of matches rather than the number of nodes:\n * - the search regexp is compiled once by the caller and reused across every\n * node (only its `lastIndex` is reset), instead of recompiling per text node,\n * - matches are pushed into a single shared array instead of allocating a new\n * array at each node and spreading child results upward.\n */\nconst collectMatchingRanges = (\n node: Node,\n regexp: RegExp,\n matchLength: number,\n rangeList: Range[],\n) => {\n if (node.nodeName === `head`) return\n\n const nodeList = node.childNodes\n\n for (let i = 0; i < nodeList.length; i++) {\n const subNode = nodeList[i]\n\n if (!subNode) {\n continue\n }\n\n if (subNode.hasChildNodes()) {\n collectMatchingRanges(subNode, regexp, matchLength, rangeList)\n }\n\n if (subNode.nodeType === 3) {\n const content = (subNode as Text).data.toLowerCase()\n if (content) {\n let match: RegExpExecArray | null = null\n regexp.lastIndex = 0\n\n // biome-ignore lint/suspicious/noAssignInExpressions: TODO\n while ((match = regexp.exec(content)) !== null) {\n if (match.index >= 0 && subNode.ownerDocument) {\n const range = subNode.ownerDocument.createRange()\n range.setStart(subNode, match.index)\n range.setEnd(subNode, match.index + matchLength)\n\n rangeList.push(range)\n }\n }\n }\n }\n }\n}\n\nconst searchNodeContainingText = (node: Node, text: string) => {\n const rangeList: Range[] = []\n\n collectMatchingRanges(node, RegExp(`(${text})`, `gi`), text.length, rangeList)\n\n return rangeList\n}\n\nexport const searchInDocument = (\n reader: Reader,\n item: SpineItem,\n doc: Document,\n text: string,\n): Observable<SearchResult> => {\n const ranges = searchNodeContainingText(doc, text)\n\n const newResults = ranges.map((range) => {\n const cfi = reader.cfi.generateCfiFromRange(range, item.item)\n\n return {\n cfi,\n } satisfies ResultItem\n })\n\n return of(newResults)\n}\n","import { deferIdle, type Reader } from \"@prose-reader/core\"\nimport { defer, forkJoin, of } from \"rxjs\"\nimport { catchError, finalize, map, switchMap } from \"rxjs/operators\"\nimport { report } from \"./report\"\nimport type { SearchResult } from \"./search\"\nimport { searchInDocument } from \"./search\"\nimport type { ResultItem, SearchEnhancerAPI } from \"./types\"\n\nexport type { ResultItem, SearchEnhancerAPI, SearchResult }\n\n/**\n * Contract of search enhancer.\n *\n * - At best a result match should be navigable. It means the search needs to\n * be done on a rendered document. This is because rendering can differ from the original\n * item resource. A resource can be something non digestible and very specific (.pdf). The search\n * enhancer is agnostic and can only search into documents.\n */\nexport const searchEnhancer =\n <InheritOptions, InheritOutput extends Reader>(\n next: (options: InheritOptions) => InheritOutput,\n ) =>\n (options: InheritOptions): InheritOutput & SearchEnhancerAPI => {\n const reader = next(options)\n\n const searchForItem = (index: number, text: string) => {\n const item = reader.spineItemsManager.get(index)\n\n if (!item) {\n return of([])\n }\n\n return deferIdle(() => reader.renderHeadless(index)).pipe(\n switchMap((result) => {\n const { doc, release } = result || {}\n\n if (!doc) return of([])\n\n return deferIdle(() =>\n searchInDocument(reader, item, doc, text),\n ).pipe(\n finalize(() => {\n release?.()\n }),\n catchError((e) => {\n report.error(e)\n\n return of([])\n }),\n )\n }),\n )\n }\n\n const search = (text: string) =>\n defer(() => {\n if (text === ``) {\n return of([])\n }\n\n const searches$ =\n reader.context.manifest?.spineItems.map((_, index) =>\n searchForItem(index, text),\n ) || []\n\n return forkJoin([...searches$, of([])])\n }).pipe(\n map((results) => {\n const flattenedResults = results.flat()\n\n report.debug(\"results\", flattenedResults)\n\n return flattenedResults\n }),\n )\n\n return {\n ...reader,\n __PROSE_READER_ENHANCER_SEARCH: true,\n search: {\n search,\n },\n }\n }\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prose-reader/enhancer-search",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.374.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"test": "vitest run --coverage"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@prose-reader/core": "^1.
|
|
27
|
+
"@prose-reader/core": "^1.374.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"rxjs": "*"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "47dc87f10804fb639e0c7fd3d48f01cf7d2e9513"
|
|
33
33
|
}
|