wiki-graph-core 0.3.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 (576) hide show
  1. package/LICENSE +201 -0
  2. package/data/editor/clue_reviewer.jinja +410 -0
  3. package/data/editor/clue_reviewer_generator.jinja +428 -0
  4. package/data/editor/revision_feedback.jinja +5 -0
  5. package/data/editor/text_compressor.jinja +127 -0
  6. package/data/guaranteed/response_intent_classifier.jinja +8 -0
  7. package/data/help/commands/archive/next.jinja +29 -0
  8. package/data/help/commands/gc.jinja +38 -0
  9. package/data/help/commands/legacy/migrate.jinja +20 -0
  10. package/data/help/commands/legacy.jinja +19 -0
  11. package/data/help/commands/maintenance/chapter/add.jinja +41 -0
  12. package/data/help/commands/maintenance/chapter/list.jinja +33 -0
  13. package/data/help/commands/maintenance/chapter/move.jinja +36 -0
  14. package/data/help/commands/maintenance/chapter/remove.jinja +26 -0
  15. package/data/help/commands/maintenance/chapter/reset.jinja +29 -0
  16. package/data/help/commands/maintenance/chapter/set-source.jinja +34 -0
  17. package/data/help/commands/maintenance/chapter/set-summary.jinja +31 -0
  18. package/data/help/commands/maintenance/chapter/set-title.jinja +29 -0
  19. package/data/help/commands/maintenance/chapter/tree.jinja +58 -0
  20. package/data/help/commands/maintenance/chapter.jinja +59 -0
  21. package/data/help/commands/maintenance/cover.jinja +28 -0
  22. package/data/help/commands/maintenance/meta.jinja +55 -0
  23. package/data/help/commands/predicate.jinja +460 -0
  24. package/data/help/commands/root.jinja +83 -0
  25. package/data/help/commands/transform.jinja +34 -0
  26. package/data/help/commands/uri.jinja +274 -0
  27. package/data/help/topics/config.jinja +88 -0
  28. package/data/help/topics/format.jinja +72 -0
  29. package/data/help/topics/readiness.jinja +99 -0
  30. package/data/help/topics/recipe.jinja +151 -0
  31. package/data/help/topics/runtime.jinja +62 -0
  32. package/data/help/topics/uri.jinja +178 -0
  33. package/data/output/epub/cover.xhtml.jinja +13 -0
  34. package/data/output/epub/nav.xhtml.jinja +12 -0
  35. package/data/output/epub/package.opf.xml.jinja +39 -0
  36. package/data/output/epub/section.xhtml.jinja +12 -0
  37. package/data/topologization/book_coherence_extraction.jinja +223 -0
  38. package/data/topologization/chunk_extraction.jinja +233 -0
  39. package/data/topologization/evidence_choice.jinja +38 -0
  40. package/data/topologization/translate_chunks.jinja +138 -0
  41. package/data/topologization/user_focused_extraction.jinja +378 -0
  42. package/dist/archive/query/archive-view.d.ts +26 -0
  43. package/dist/archive/query/archive-view.js +4540 -0
  44. package/dist/archive/query/archive-view.js.map +1 -0
  45. package/dist/archive/query/continuation-cursor.d.ts +61 -0
  46. package/dist/archive/query/continuation-cursor.js +363 -0
  47. package/dist/archive/query/continuation-cursor.js.map +1 -0
  48. package/dist/archive/query/index.d.ts +29 -0
  49. package/dist/archive/query/index.js +63 -0
  50. package/dist/archive/query/index.js.map +1 -0
  51. package/dist/archive/query/lexical-search.d.ts +22 -0
  52. package/dist/archive/query/lexical-search.js +137 -0
  53. package/dist/archive/query/lexical-search.js.map +1 -0
  54. package/dist/archive/query/search-cache.d.ts +192 -0
  55. package/dist/archive/query/search-cache.js +1248 -0
  56. package/dist/archive/query/search-cache.js.map +1 -0
  57. package/dist/archive/search-index/index.d.ts +26 -0
  58. package/dist/archive/search-index/index.js +29 -0
  59. package/dist/archive/search-index/index.js.map +1 -0
  60. package/dist/archive/search-index/search-index.d.ts +26 -0
  61. package/dist/archive/search-index/search-index.js +555 -0
  62. package/dist/archive/search-index/search-index.js.map +1 -0
  63. package/dist/archive/search-index/search-tokenizer.d.ts +16 -0
  64. package/dist/archive/search-index/search-tokenizer.js +225 -0
  65. package/dist/archive/search-index/search-tokenizer.js.map +1 -0
  66. package/dist/common/cli-command.d.ts +4 -0
  67. package/dist/common/cli-command.js +7 -0
  68. package/dist/common/cli-command.js.map +1 -0
  69. package/dist/common/data-dir.d.ts +3 -0
  70. package/dist/common/data-dir.js +48 -0
  71. package/dist/common/data-dir.js.map +1 -0
  72. package/dist/common/language.d.ts +55 -0
  73. package/dist/common/language.js +208 -0
  74. package/dist/common/language.js.map +1 -0
  75. package/dist/common/llm-scope.d.ts +19 -0
  76. package/dist/common/llm-scope.js +31 -0
  77. package/dist/common/llm-scope.js.map +1 -0
  78. package/dist/common/logging.d.ts +22 -0
  79. package/dist/common/logging.js +141 -0
  80. package/dist/common/logging.js.map +1 -0
  81. package/dist/common/template.d.ts +8 -0
  82. package/dist/common/template.js +54 -0
  83. package/dist/common/template.js.map +1 -0
  84. package/dist/common/tinyld-language.d.ts +6 -0
  85. package/dist/common/tinyld-language.js +34 -0
  86. package/dist/common/tinyld-language.js.map +1 -0
  87. package/dist/common/wiki-graph-dir.d.ts +10 -0
  88. package/dist/common/wiki-graph-dir.js +41 -0
  89. package/dist/common/wiki-graph-dir.js.map +1 -0
  90. package/dist/common/wiki-graph-temp.d.ts +6 -0
  91. package/dist/common/wiki-graph-temp.js +21 -0
  92. package/dist/common/wiki-graph-temp.js.map +1 -0
  93. package/dist/common/wiki-graph-uri.d.ts +28 -0
  94. package/dist/common/wiki-graph-uri.js +171 -0
  95. package/dist/common/wiki-graph-uri.js.map +1 -0
  96. package/dist/context/index.d.ts +1 -0
  97. package/dist/context/index.js +13 -0
  98. package/dist/context/index.js.map +1 -0
  99. package/dist/context/task-context.d.ts +41 -0
  100. package/dist/context/task-context.js +111 -0
  101. package/dist/context/task-context.js.map +1 -0
  102. package/dist/document/database.d.ts +30 -0
  103. package/dist/document/database.js +273 -0
  104. package/dist/document/database.js.map +1 -0
  105. package/dist/document/document.d.ts +153 -0
  106. package/dist/document/document.js +615 -0
  107. package/dist/document/document.js.map +1 -0
  108. package/dist/document/fragments.d.ts +63 -0
  109. package/dist/document/fragments.js +371 -0
  110. package/dist/document/fragments.js.map +1 -0
  111. package/dist/document/index.d.ts +13 -0
  112. package/dist/document/index.js +62 -0
  113. package/dist/document/index.js.map +1 -0
  114. package/dist/document/schema.d.ts +8 -0
  115. package/dist/document/schema.js +472 -0
  116. package/dist/document/schema.js.map +1 -0
  117. package/dist/document/shared-state-database.d.ts +9 -0
  118. package/dist/document/shared-state-database.js +193 -0
  119. package/dist/document/shared-state-database.js.map +1 -0
  120. package/dist/document/stores.d.ts +203 -0
  121. package/dist/document/stores.js +1678 -0
  122. package/dist/document/stores.js.map +1 -0
  123. package/dist/document/text-streams.d.ts +86 -0
  124. package/dist/document/text-streams.js +515 -0
  125. package/dist/document/text-streams.js.map +1 -0
  126. package/dist/document/types.d.ts +148 -0
  127. package/dist/document/types.js +69 -0
  128. package/dist/document/types.js.map +1 -0
  129. package/dist/editor/clue.d.ts +27 -0
  130. package/dist/editor/clue.js +158 -0
  131. package/dist/editor/clue.js.map +1 -0
  132. package/dist/editor/compressor.d.ts +18 -0
  133. package/dist/editor/compressor.js +68 -0
  134. package/dist/editor/compressor.js.map +1 -0
  135. package/dist/editor/editor.d.ts +39 -0
  136. package/dist/editor/editor.js +253 -0
  137. package/dist/editor/editor.js.map +1 -0
  138. package/dist/editor/feedback.d.ts +16 -0
  139. package/dist/editor/feedback.js +104 -0
  140. package/dist/editor/feedback.js.map +1 -0
  141. package/dist/editor/index.d.ts +17 -0
  142. package/dist/editor/index.js +5 -0
  143. package/dist/editor/index.js.map +1 -0
  144. package/dist/editor/language-review.d.ts +14 -0
  145. package/dist/editor/language-review.js +35 -0
  146. package/dist/editor/language-review.js.map +1 -0
  147. package/dist/editor/log.d.ts +37 -0
  148. package/dist/editor/log.js +202 -0
  149. package/dist/editor/log.js.map +1 -0
  150. package/dist/editor/markup.d.ts +20 -0
  151. package/dist/editor/markup.js +294 -0
  152. package/dist/editor/markup.js.map +1 -0
  153. package/dist/editor/prompt-templates.d.ts +6 -0
  154. package/dist/editor/prompt-templates.js +11 -0
  155. package/dist/editor/prompt-templates.js.map +1 -0
  156. package/dist/editor/response.d.ts +5 -0
  157. package/dist/editor/response.js +31 -0
  158. package/dist/editor/response.js.map +1 -0
  159. package/dist/editor/review.d.ts +34 -0
  160. package/dist/editor/review.js +189 -0
  161. package/dist/editor/review.js.map +1 -0
  162. package/dist/editor/types.d.ts +31 -0
  163. package/dist/editor/types.js +21 -0
  164. package/dist/editor/types.js.map +1 -0
  165. package/dist/evidence-selection/anchor-resolver.d.ts +43 -0
  166. package/dist/evidence-selection/anchor-resolver.js +783 -0
  167. package/dist/evidence-selection/anchor-resolver.js.map +1 -0
  168. package/dist/evidence-selection/anchor-types.d.ts +27 -0
  169. package/dist/evidence-selection/anchor-types.js +1 -0
  170. package/dist/evidence-selection/anchor-types.js.map +1 -0
  171. package/dist/evidence-selection/index.d.ts +8 -0
  172. package/dist/evidence-selection/index.js +32 -0
  173. package/dist/evidence-selection/index.js.map +1 -0
  174. package/dist/evidence-selection/prompt.d.ts +18 -0
  175. package/dist/evidence-selection/prompt.js +54 -0
  176. package/dist/evidence-selection/prompt.js.map +1 -0
  177. package/dist/evidence-selection/quote-score.d.ts +29 -0
  178. package/dist/evidence-selection/quote-score.js +331 -0
  179. package/dist/evidence-selection/quote-score.js.map +1 -0
  180. package/dist/evidence-selection/selection-resolver.d.ts +19 -0
  181. package/dist/evidence-selection/selection-resolver.js +303 -0
  182. package/dist/evidence-selection/selection-resolver.js.map +1 -0
  183. package/dist/evidence-selection/text.d.ts +4 -0
  184. package/dist/evidence-selection/text.js +66 -0
  185. package/dist/evidence-selection/text.js.map +1 -0
  186. package/dist/evidence-selection/types.d.ts +36 -0
  187. package/dist/evidence-selection/types.js +1 -0
  188. package/dist/evidence-selection/types.js.map +1 -0
  189. package/dist/facade/app.d.ts +75 -0
  190. package/dist/facade/app.js +141 -0
  191. package/dist/facade/app.js.map +1 -0
  192. package/dist/facade/build-queue.d.ts +181 -0
  193. package/dist/facade/build-queue.js +1442 -0
  194. package/dist/facade/build-queue.js.map +1 -0
  195. package/dist/facade/chapter-build.d.ts +60 -0
  196. package/dist/facade/chapter-build.js +1020 -0
  197. package/dist/facade/chapter-build.js.map +1 -0
  198. package/dist/facade/chapter.d.ts +168 -0
  199. package/dist/facade/chapter.js +944 -0
  200. package/dist/facade/chapter.js.map +1 -0
  201. package/dist/facade/digest.d.ts +55 -0
  202. package/dist/facade/digest.js +168 -0
  203. package/dist/facade/digest.js.map +1 -0
  204. package/dist/facade/graph.d.ts +60 -0
  205. package/dist/facade/graph.js +203 -0
  206. package/dist/facade/graph.js.map +1 -0
  207. package/dist/facade/import.d.ts +49 -0
  208. package/dist/facade/import.js +262 -0
  209. package/dist/facade/import.js.map +1 -0
  210. package/dist/facade/index.d.ts +39 -0
  211. package/dist/facade/index.js +171 -0
  212. package/dist/facade/index.js.map +1 -0
  213. package/dist/facade/knowledge-graph-build.d.ts +75 -0
  214. package/dist/facade/knowledge-graph-build.js +897 -0
  215. package/dist/facade/knowledge-graph-build.js.map +1 -0
  216. package/dist/facade/llm-sampling.d.ts +11 -0
  217. package/dist/facade/llm-sampling.js +58 -0
  218. package/dist/facade/llm-sampling.js.map +1 -0
  219. package/dist/facade/types.d.ts +8 -0
  220. package/dist/facade/types.js +1 -0
  221. package/dist/facade/types.js.map +1 -0
  222. package/dist/facade/wiki-graph-archive.d.ts +41 -0
  223. package/dist/facade/wiki-graph-archive.js +130 -0
  224. package/dist/facade/wiki-graph-archive.js.map +1 -0
  225. package/dist/gc/files.d.ts +15 -0
  226. package/dist/gc/files.js +141 -0
  227. package/dist/gc/files.js.map +1 -0
  228. package/dist/gc/index.d.ts +2 -0
  229. package/dist/gc/index.js +5 -0
  230. package/dist/gc/index.js.map +1 -0
  231. package/dist/gc/lock.d.ts +3 -0
  232. package/dist/gc/lock.js +137 -0
  233. package/dist/gc/lock.js.map +1 -0
  234. package/dist/gc/runner.d.ts +9 -0
  235. package/dist/gc/runner.js +129 -0
  236. package/dist/gc/runner.js.map +1 -0
  237. package/dist/gc/tmp-gc.d.ts +5 -0
  238. package/dist/gc/tmp-gc.js +57 -0
  239. package/dist/gc/tmp-gc.js.map +1 -0
  240. package/dist/gc/types.d.ts +24 -0
  241. package/dist/gc/types.js +1 -0
  242. package/dist/gc/types.js.map +1 -0
  243. package/dist/gc.cjs +10041 -0
  244. package/dist/gc.cjs.map +1 -0
  245. package/dist/gc.d.cts +10 -0
  246. package/dist/gc.d.ts +2 -0
  247. package/dist/gc.js +5 -0
  248. package/dist/gc.js.map +1 -0
  249. package/dist/guaranteed/classifier.d.ts +10 -0
  250. package/dist/guaranteed/classifier.js +88 -0
  251. package/dist/guaranteed/classifier.js.map +1 -0
  252. package/dist/guaranteed/errors.d.ts +38 -0
  253. package/dist/guaranteed/errors.js +73 -0
  254. package/dist/guaranteed/errors.js.map +1 -0
  255. package/dist/guaranteed/index.d.ts +7 -0
  256. package/dist/guaranteed/index.js +21 -0
  257. package/dist/guaranteed/index.js.map +1 -0
  258. package/dist/guaranteed/request.d.ts +8 -0
  259. package/dist/guaranteed/request.js +206 -0
  260. package/dist/guaranteed/request.js.map +1 -0
  261. package/dist/guaranteed/response.d.ts +12 -0
  262. package/dist/guaranteed/response.js +98 -0
  263. package/dist/guaranteed/response.js.map +1 -0
  264. package/dist/guaranteed/types.d.ts +20 -0
  265. package/dist/guaranteed/types.js +1 -0
  266. package/dist/guaranteed/types.js.map +1 -0
  267. package/dist/index-B8NNnQ8P.d.ts +424 -0
  268. package/dist/index.cjs +34774 -0
  269. package/dist/index.cjs.map +1 -0
  270. package/dist/index.d.cts +2462 -0
  271. package/dist/index.d.ts +79 -0
  272. package/dist/index.js +168 -0
  273. package/dist/index.js.map +1 -0
  274. package/dist/legacy-sdpub/upgrade.d.ts +7 -0
  275. package/dist/legacy-sdpub/upgrade.js +795 -0
  276. package/dist/legacy-sdpub/upgrade.js.map +1 -0
  277. package/dist/llm/cache.d.ts +13 -0
  278. package/dist/llm/cache.js +35 -0
  279. package/dist/llm/cache.js.map +1 -0
  280. package/dist/llm/client.d.ts +26 -0
  281. package/dist/llm/client.js +572 -0
  282. package/dist/llm/client.js.map +1 -0
  283. package/dist/llm/context.d.ts +22 -0
  284. package/dist/llm/context.js +78 -0
  285. package/dist/llm/context.js.map +1 -0
  286. package/dist/llm/errors.d.ts +7 -0
  287. package/dist/llm/errors.js +12 -0
  288. package/dist/llm/errors.js.map +1 -0
  289. package/dist/llm/index.d.ts +7 -0
  290. package/dist/llm/index.js +17 -0
  291. package/dist/llm/index.js.map +1 -0
  292. package/dist/llm/request-log.d.ts +9 -0
  293. package/dist/llm/request-log.js +35 -0
  294. package/dist/llm/request-log.js.map +1 -0
  295. package/dist/llm/sampling.d.ts +11 -0
  296. package/dist/llm/sampling.js +67 -0
  297. package/dist/llm/sampling.js.map +1 -0
  298. package/dist/llm/types.d.ts +50 -0
  299. package/dist/llm/types.js +1 -0
  300. package/dist/llm/types.js.map +1 -0
  301. package/dist/output/epub/archive.d.ts +9 -0
  302. package/dist/output/epub/archive.js +81 -0
  303. package/dist/output/epub/archive.js.map +1 -0
  304. package/dist/output/epub/book.d.ts +15 -0
  305. package/dist/output/epub/book.js +76 -0
  306. package/dist/output/epub/book.js.map +1 -0
  307. package/dist/output/epub/content.d.ts +9 -0
  308. package/dist/output/epub/content.js +35 -0
  309. package/dist/output/epub/content.js.map +1 -0
  310. package/dist/output/epub/index.d.ts +20 -0
  311. package/dist/output/epub/index.js +14 -0
  312. package/dist/output/epub/index.js.map +1 -0
  313. package/dist/output/epub/model.d.ts +24 -0
  314. package/dist/output/epub/model.js +1 -0
  315. package/dist/output/epub/model.js.map +1 -0
  316. package/dist/output/epub/navigation.d.ts +10 -0
  317. package/dist/output/epub/navigation.js +39 -0
  318. package/dist/output/epub/navigation.js.map +1 -0
  319. package/dist/output/epub/package.d.ts +17 -0
  320. package/dist/output/epub/package.js +29 -0
  321. package/dist/output/epub/package.js.map +1 -0
  322. package/dist/output/epub/shared.d.ts +4 -0
  323. package/dist/output/epub/shared.js +12 -0
  324. package/dist/output/epub/shared.js.map +1 -0
  325. package/dist/output/epub/templates.d.ts +35 -0
  326. package/dist/output/epub/templates.js +26 -0
  327. package/dist/output/epub/templates.js.map +1 -0
  328. package/dist/output/index.d.ts +14 -0
  329. package/dist/output/index.js +11 -0
  330. package/dist/output/index.js.map +1 -0
  331. package/dist/output/plain-text.d.ts +18 -0
  332. package/dist/output/plain-text.js +56 -0
  333. package/dist/output/plain-text.js.map +1 -0
  334. package/dist/progress/index.d.ts +3 -0
  335. package/dist/progress/index.js +14 -0
  336. package/dist/progress/index.js.map +1 -0
  337. package/dist/progress/reporter.d.ts +10 -0
  338. package/dist/progress/reporter.js +79 -0
  339. package/dist/progress/reporter.js.map +1 -0
  340. package/dist/progress/tracker.d.ts +37 -0
  341. package/dist/progress/tracker.js +119 -0
  342. package/dist/progress/tracker.js.map +1 -0
  343. package/dist/progress/types.d.ts +28 -0
  344. package/dist/progress/types.js +1 -0
  345. package/dist/progress/types.js.map +1 -0
  346. package/dist/reader/attention/attention.d.ts +39 -0
  347. package/dist/reader/attention/attention.js +123 -0
  348. package/dist/reader/attention/attention.js.map +1 -0
  349. package/dist/reader/attention/index.d.ts +9 -0
  350. package/dist/reader/attention/index.js +5 -0
  351. package/dist/reader/attention/index.js.map +1 -0
  352. package/dist/reader/attention/wave-reflection.d.ts +21 -0
  353. package/dist/reader/attention/wave-reflection.js +153 -0
  354. package/dist/reader/attention/wave-reflection.js.map +1 -0
  355. package/dist/reader/attention/working-memory.d.ts +28 -0
  356. package/dist/reader/attention/working-memory.js +62 -0
  357. package/dist/reader/attention/working-memory.js.map +1 -0
  358. package/dist/reader/chunk-batch/extract.d.ts +13 -0
  359. package/dist/reader/chunk-batch/extract.js +14 -0
  360. package/dist/reader/chunk-batch/extract.js.map +1 -0
  361. package/dist/reader/chunk-batch/extractor.d.ts +17 -0
  362. package/dist/reader/chunk-batch/extractor.js +337 -0
  363. package/dist/reader/chunk-batch/extractor.js.map +1 -0
  364. package/dist/reader/chunk-batch/fragment-projection.d.ts +34 -0
  365. package/dist/reader/chunk-batch/fragment-projection.js +94 -0
  366. package/dist/reader/chunk-batch/fragment-projection.js.map +1 -0
  367. package/dist/reader/chunk-batch/index.d.ts +12 -0
  368. package/dist/reader/chunk-batch/index.js +13 -0
  369. package/dist/reader/chunk-batch/index.js.map +1 -0
  370. package/dist/reader/chunk-batch/language.d.ts +9 -0
  371. package/dist/reader/chunk-batch/language.js +23 -0
  372. package/dist/reader/chunk-batch/language.js.map +1 -0
  373. package/dist/reader/chunk-batch/parser.d.ts +94 -0
  374. package/dist/reader/chunk-batch/parser.js +640 -0
  375. package/dist/reader/chunk-batch/parser.js.map +1 -0
  376. package/dist/reader/chunk-batch/prompt-templates.d.ts +6 -0
  377. package/dist/reader/chunk-batch/prompt-templates.js +11 -0
  378. package/dist/reader/chunk-batch/prompt-templates.js.map +1 -0
  379. package/dist/reader/chunk-batch/types.d.ts +85 -0
  380. package/dist/reader/chunk-batch/types.js +1 -0
  381. package/dist/reader/chunk-batch/types.js.map +1 -0
  382. package/dist/reader/index.d.ts +13 -0
  383. package/dist/reader/index.js +7 -0
  384. package/dist/reader/index.js.map +1 -0
  385. package/dist/reader/reader.d.ts +37 -0
  386. package/dist/reader/reader.js +82 -0
  387. package/dist/reader/reader.js.map +1 -0
  388. package/dist/reader/segment/index.d.ts +2 -0
  389. package/dist/reader/segment/index.js +5 -0
  390. package/dist/reader/segment/index.js.map +1 -0
  391. package/dist/reader/segment/intl-segmenter.d.ts +5 -0
  392. package/dist/reader/segment/intl-segmenter.js +102 -0
  393. package/dist/reader/segment/intl-segmenter.js.map +1 -0
  394. package/dist/reader/segment/segment.d.ts +5 -0
  395. package/dist/reader/segment/segment.js +9 -0
  396. package/dist/reader/segment/segment.js.map +1 -0
  397. package/dist/reader/segment/types.d.ts +14 -0
  398. package/dist/reader/segment/types.js +1 -0
  399. package/dist/reader/segment/types.js.map +1 -0
  400. package/dist/reader/types.d.ts +29 -0
  401. package/dist/reader/types.js +1 -0
  402. package/dist/reader/types.js.map +1 -0
  403. package/dist/serial.d.ts +89 -0
  404. package/dist/serial.js +476 -0
  405. package/dist/serial.js.map +1 -0
  406. package/dist/source/adapter.d.ts +15 -0
  407. package/dist/source/adapter.js +1 -0
  408. package/dist/source/adapter.js.map +1 -0
  409. package/dist/source/epub/archive.d.ts +27 -0
  410. package/dist/source/epub/archive.js +189 -0
  411. package/dist/source/epub/archive.js.map +1 -0
  412. package/dist/source/epub/content.d.ts +22 -0
  413. package/dist/source/epub/content.js +183 -0
  414. package/dist/source/epub/content.js.map +1 -0
  415. package/dist/source/epub/document.d.ts +55 -0
  416. package/dist/source/epub/document.js +179 -0
  417. package/dist/source/epub/document.js.map +1 -0
  418. package/dist/source/epub/index.d.ts +10 -0
  419. package/dist/source/epub/index.js +6 -0
  420. package/dist/source/epub/index.js.map +1 -0
  421. package/dist/source/epub/navigation.d.ts +16 -0
  422. package/dist/source/epub/navigation.js +215 -0
  423. package/dist/source/epub/navigation.js.map +1 -0
  424. package/dist/source/epub/package.d.ts +33 -0
  425. package/dist/source/epub/package.js +237 -0
  426. package/dist/source/epub/package.js.map +1 -0
  427. package/dist/source/epub/xml.d.ts +16 -0
  428. package/dist/source/epub/xml.js +111 -0
  429. package/dist/source/epub/xml.js.map +1 -0
  430. package/dist/source/index.d.ts +12 -0
  431. package/dist/source/index.js +32 -0
  432. package/dist/source/index.js.map +1 -0
  433. package/dist/source/meta.d.ts +30 -0
  434. package/dist/source/meta.js +22 -0
  435. package/dist/source/meta.js.map +1 -0
  436. package/dist/source/plain-text.d.ts +16 -0
  437. package/dist/source/plain-text.js +86 -0
  438. package/dist/source/plain-text.js.map +1 -0
  439. package/dist/source/toc.d.ts +16 -0
  440. package/dist/source/toc.js +17 -0
  441. package/dist/source/toc.js.map +1 -0
  442. package/dist/source/types.d.ts +16 -0
  443. package/dist/source/types.js +1 -0
  444. package/dist/source/types.js.map +1 -0
  445. package/dist/topology/grouping.d.ts +15 -0
  446. package/dist/topology/grouping.js +18 -0
  447. package/dist/topology/grouping.js.map +1 -0
  448. package/dist/topology/index.d.ts +21 -0
  449. package/dist/topology/index.js +5 -0
  450. package/dist/topology/index.js.map +1 -0
  451. package/dist/topology/resource-segmentation.d.ts +13 -0
  452. package/dist/topology/resource-segmentation.js +111 -0
  453. package/dist/topology/resource-segmentation.js.map +1 -0
  454. package/dist/topology/segment-incision.d.ts +18 -0
  455. package/dist/topology/segment-incision.js +197 -0
  456. package/dist/topology/segment-incision.js.map +1 -0
  457. package/dist/topology/snake-detector.d.ts +13 -0
  458. package/dist/topology/snake-detector.js +520 -0
  459. package/dist/topology/snake-detector.js.map +1 -0
  460. package/dist/topology/snake-graph-builder.d.ts +14 -0
  461. package/dist/topology/snake-graph-builder.js +76 -0
  462. package/dist/topology/snake-graph-builder.js.map +1 -0
  463. package/dist/topology/topology.d.ts +29 -0
  464. package/dist/topology/topology.js +348 -0
  465. package/dist/topology/topology.js.map +1 -0
  466. package/dist/topology/weights.d.ts +10 -0
  467. package/dist/topology/weights.js +84 -0
  468. package/dist/topology/weights.js.map +1 -0
  469. package/dist/types-FVIqiLC9.d.cts +24 -0
  470. package/dist/utils/async-semaphore.d.ts +7 -0
  471. package/dist/utils/async-semaphore.js +40 -0
  472. package/dist/utils/async-semaphore.js.map +1 -0
  473. package/dist/utils/enum.d.ts +5 -0
  474. package/dist/utils/enum.js +18 -0
  475. package/dist/utils/enum.js.map +1 -0
  476. package/dist/utils/hash.d.ts +3 -0
  477. package/dist/utils/hash.js +132 -0
  478. package/dist/utils/hash.js.map +1 -0
  479. package/dist/utils/node-error.d.ts +4 -0
  480. package/dist/utils/node-error.js +59 -0
  481. package/dist/utils/node-error.js.map +1 -0
  482. package/dist/wikg/archive-uri.d.ts +1 -0
  483. package/dist/wikg/archive-uri.js +37 -0
  484. package/dist/wikg/archive-uri.js.map +1 -0
  485. package/dist/wikg/archive.d.ts +28 -0
  486. package/dist/wikg/archive.js +496 -0
  487. package/dist/wikg/archive.js.map +1 -0
  488. package/dist/wikg/index.d.ts +31 -0
  489. package/dist/wikg/index.js +60 -0
  490. package/dist/wikg/index.js.map +1 -0
  491. package/dist/wikg/wikg-coordinator.d.ts +45 -0
  492. package/dist/wikg/wikg-coordinator.js +1687 -0
  493. package/dist/wikg/wikg-coordinator.js.map +1 -0
  494. package/dist/wikg/wiki-graph-archive-file.d.ts +42 -0
  495. package/dist/wikg/wiki-graph-archive-file.js +78 -0
  496. package/dist/wikg/wiki-graph-archive-file.js.map +1 -0
  497. package/dist/wikilink/index.d.ts +10 -0
  498. package/dist/wikilink/index.js +7 -0
  499. package/dist/wikilink/index.js.map +1 -0
  500. package/dist/wikilink/relation-discovery.d.ts +31 -0
  501. package/dist/wikilink/relation-discovery.js +477 -0
  502. package/dist/wikilink/relation-discovery.js.map +1 -0
  503. package/dist/wikilink/types.d.ts +23 -0
  504. package/dist/wikilink/types.js +1 -0
  505. package/dist/wikilink/types.js.map +1 -0
  506. package/dist/wikilink/window.d.ts +7 -0
  507. package/dist/wikilink/window.js +53 -0
  508. package/dist/wikilink/window.js.map +1 -0
  509. package/dist/wikimatch/enrichment.d.ts +10 -0
  510. package/dist/wikimatch/enrichment.js +55 -0
  511. package/dist/wikimatch/enrichment.js.map +1 -0
  512. package/dist/wikimatch/index.d.ts +16 -0
  513. package/dist/wikimatch/index.js +66 -0
  514. package/dist/wikimatch/index.js.map +1 -0
  515. package/dist/wikimatch/option-narrowing.d.ts +17 -0
  516. package/dist/wikimatch/option-narrowing.js +208 -0
  517. package/dist/wikimatch/option-narrowing.js.map +1 -0
  518. package/dist/wikimatch/options.d.ts +14 -0
  519. package/dist/wikimatch/options.js +155 -0
  520. package/dist/wikimatch/options.js.map +1 -0
  521. package/dist/wikimatch/policy-judge.d.ts +17 -0
  522. package/dist/wikimatch/policy-judge.js +430 -0
  523. package/dist/wikimatch/policy-judge.js.map +1 -0
  524. package/dist/wikimatch/range-suppression.d.ts +9 -0
  525. package/dist/wikimatch/range-suppression.js +27 -0
  526. package/dist/wikimatch/range-suppression.js.map +1 -0
  527. package/dist/wikimatch/surface-screening.d.ts +16 -0
  528. package/dist/wikimatch/surface-screening.js +168 -0
  529. package/dist/wikimatch/surface-screening.js.map +1 -0
  530. package/dist/wikimatch/surface-window.d.ts +6 -0
  531. package/dist/wikimatch/surface-window.js +44 -0
  532. package/dist/wikimatch/surface-window.js.map +1 -0
  533. package/dist/wikimatch/types.d.ts +151 -0
  534. package/dist/wikimatch/types.js +1 -0
  535. package/dist/wikimatch/types.js.map +1 -0
  536. package/dist/wikimatch/wikispine.d.ts +43 -0
  537. package/dist/wikimatch/wikispine.js +399 -0
  538. package/dist/wikimatch/wikispine.js.map +1 -0
  539. package/dist/wikimatch/window.d.ts +6 -0
  540. package/dist/wikimatch/window.js +83 -0
  541. package/dist/wikimatch/window.js.map +1 -0
  542. package/dist/wikimatch/words.d.ts +16 -0
  543. package/dist/wikimatch/words.js +66 -0
  544. package/dist/wikimatch/words.js.map +1 -0
  545. package/dist/wikipage/cache.d.ts +18 -0
  546. package/dist/wikipage/cache.js +404 -0
  547. package/dist/wikipage/cache.js.map +1 -0
  548. package/dist/wikipage/fetch-log.d.ts +17 -0
  549. package/dist/wikipage/fetch-log.js +143 -0
  550. package/dist/wikipage/fetch-log.js.map +1 -0
  551. package/dist/wikipage/index.d.ts +14 -0
  552. package/dist/wikipage/index.js +17 -0
  553. package/dist/wikipage/index.js.map +1 -0
  554. package/dist/wikipage/normalizer.d.ts +14 -0
  555. package/dist/wikipage/normalizer.js +147 -0
  556. package/dist/wikipage/normalizer.js.map +1 -0
  557. package/dist/wikipage/rate-limiter.d.ts +13 -0
  558. package/dist/wikipage/rate-limiter.js +84 -0
  559. package/dist/wikipage/rate-limiter.js.map +1 -0
  560. package/dist/wikipage/resolver.d.ts +26 -0
  561. package/dist/wikipage/resolver.js +325 -0
  562. package/dist/wikipage/resolver.js.map +1 -0
  563. package/dist/wikipage/types.d.ts +96 -0
  564. package/dist/wikipage/types.js +1 -0
  565. package/dist/wikipage/types.js.map +1 -0
  566. package/dist/wikipage/wikimedia-client.d.ts +48 -0
  567. package/dist/wikipage/wikimedia-client.js +397 -0
  568. package/dist/wikipage/wikimedia-client.js.map +1 -0
  569. package/dist/worker-BgQ0Xl8T.d.cts +181 -0
  570. package/dist/worker.cjs +5259 -0
  571. package/dist/worker.cjs.map +1 -0
  572. package/dist/worker.d.cts +2 -0
  573. package/dist/worker.d.ts +2 -0
  574. package/dist/worker.js +5 -0
  575. package/dist/worker.js.map +1 -0
  576. package/package.json +78 -0
@@ -0,0 +1,1248 @@
1
+ import { createHash } from "crypto";
2
+ import { stat } from "fs/promises";
3
+ import { join } from "path";
4
+ import { resolveWikiGraphCacheDirectoryPath } from "../../common/wiki-graph-dir.js";
5
+ import { getNumber, getString } from "../../document/database.js";
6
+ import { openSharedStateDatabase } from "../../document/index.js";
7
+ import { isNodeError } from "../../utils/node-error.js";
8
+ const SEARCH_EVIDENCE_KIND = {
9
+ mention: 1,
10
+ mentionLink: 2,
11
+ chunk: 3
12
+ };
13
+ const SEARCH_SESSION_SCHEMA_SQL = `
14
+ CREATE TABLE IF NOT EXISTS search_sessions (
15
+ session_id TEXT PRIMARY KEY,
16
+ archive_key TEXT NOT NULL,
17
+ query TEXT NOT NULL,
18
+ options_json TEXT NOT NULL,
19
+ terms_json TEXT NOT NULL,
20
+ lens TEXT NOT NULL,
21
+ match TEXT NOT NULL,
22
+ object_caches_populated INTEGER NOT NULL DEFAULT 0,
23
+ created_at INTEGER NOT NULL,
24
+ expires_at INTEGER NOT NULL,
25
+ accessed_at INTEGER NOT NULL
26
+ );
27
+
28
+ CREATE TABLE IF NOT EXISTS search_results (
29
+ session_id TEXT NOT NULL,
30
+ rank INTEGER NOT NULL,
31
+ item_json TEXT NOT NULL,
32
+ PRIMARY KEY (session_id, rank)
33
+ );
34
+
35
+ CREATE TABLE IF NOT EXISTS predicate_dictionary (
36
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
37
+ value TEXT NOT NULL UNIQUE
38
+ );
39
+
40
+ CREATE TABLE IF NOT EXISTS search_evidence_hit_events (
41
+ session_id TEXT NOT NULL,
42
+ evidence_kind INTEGER NOT NULL,
43
+ evidence_id TEXT NOT NULL,
44
+ chapter_id INTEGER NOT NULL,
45
+ sentence_index INTEGER NOT NULL,
46
+ score REAL NOT NULL,
47
+ PRIMARY KEY (
48
+ session_id,
49
+ evidence_kind,
50
+ evidence_id,
51
+ chapter_id,
52
+ sentence_index
53
+ )
54
+ );
55
+
56
+ CREATE INDEX IF NOT EXISTS idx_search_evidence_hit_events_evidence_rank
57
+ ON search_evidence_hit_events(session_id, evidence_kind, evidence_id, score DESC, chapter_id, sentence_index);
58
+
59
+ CREATE INDEX IF NOT EXISTS idx_search_evidence_hit_events_sentence
60
+ ON search_evidence_hit_events(session_id, chapter_id, sentence_index, evidence_kind, evidence_id);
61
+
62
+ CREATE TABLE IF NOT EXISTS search_entity_hits (
63
+ session_id TEXT NOT NULL,
64
+ qid TEXT NOT NULL,
65
+ property_top_scores_json TEXT NOT NULL DEFAULT '[]',
66
+ evidence_top_scores_json TEXT NOT NULL DEFAULT '[]',
67
+ property_score REAL NOT NULL DEFAULT 0,
68
+ evidence_score REAL NOT NULL DEFAULT 0,
69
+ result_score REAL NOT NULL DEFAULT 0,
70
+ PRIMARY KEY (session_id, qid)
71
+ );
72
+
73
+ CREATE INDEX IF NOT EXISTS idx_search_entity_hits_rank
74
+ ON search_entity_hits(session_id, result_score DESC, qid);
75
+
76
+ CREATE TABLE IF NOT EXISTS search_triple_hits (
77
+ session_id TEXT NOT NULL,
78
+ subject_qid TEXT NOT NULL,
79
+ predicate_id INTEGER NOT NULL,
80
+ object_qid TEXT NOT NULL,
81
+ evidence_top_scores_json TEXT NOT NULL DEFAULT '[]',
82
+ result_score REAL NOT NULL DEFAULT 0,
83
+ PRIMARY KEY (session_id, subject_qid, predicate_id, object_qid),
84
+ FOREIGN KEY (predicate_id) REFERENCES predicate_dictionary(id)
85
+ );
86
+
87
+ CREATE INDEX IF NOT EXISTS idx_search_triple_hits_rank
88
+ ON search_triple_hits(session_id, result_score DESC, subject_qid, predicate_id, object_qid);
89
+
90
+ CREATE TABLE IF NOT EXISTS search_chunk_hits (
91
+ session_id TEXT NOT NULL,
92
+ chunk_id INTEGER NOT NULL,
93
+ property_top_scores_json TEXT NOT NULL DEFAULT '[]',
94
+ evidence_top_scores_json TEXT NOT NULL DEFAULT '[]',
95
+ property_score REAL NOT NULL DEFAULT 0,
96
+ evidence_score REAL NOT NULL DEFAULT 0,
97
+ result_score REAL NOT NULL DEFAULT 0,
98
+ PRIMARY KEY (session_id, chunk_id)
99
+ );
100
+
101
+ CREATE INDEX IF NOT EXISTS idx_search_chunk_hits_rank
102
+ ON search_chunk_hits(session_id, result_score DESC, chunk_id);
103
+
104
+ CREATE INDEX IF NOT EXISTS idx_search_sessions_archive
105
+ ON search_sessions(archive_key, session_id);
106
+
107
+ CREATE INDEX IF NOT EXISTS idx_search_sessions_expires
108
+ ON search_sessions(expires_at);
109
+
110
+ CREATE INDEX IF NOT EXISTS idx_search_sessions_prune
111
+ ON search_sessions(accessed_at DESC, created_at DESC, session_id);
112
+ `;
113
+ const SEARCH_RANKING_VERSION = 6;
114
+ const SEARCH_SESSION_MAX_COUNT = 500;
115
+ const SEARCH_SESSION_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
116
+ const SEARCH_TOP_SCORE_COUNT = 10;
117
+ async function readCachedSearchSessionPage(input, offset, limit) {
118
+ const sessionId = createSearchSessionId(input);
119
+ if (!await hasSearchSession(sessionId, input.archiveKey)) {
120
+ return void 0;
121
+ }
122
+ return await readSearchSessionPage(
123
+ sessionId,
124
+ offset,
125
+ limit,
126
+ input.archiveKey
127
+ );
128
+ }
129
+ async function readCachedEntitySearchSessionPage(input, offset, limit) {
130
+ const sessionId = createEntitySearchSessionId(input);
131
+ if (!await hasSearchSession(sessionId, input.archiveKey)) {
132
+ return void 0;
133
+ }
134
+ return await readEntitySearchSessionPage(
135
+ sessionId,
136
+ offset,
137
+ limit,
138
+ input.archiveKey
139
+ );
140
+ }
141
+ async function createSearchSession(input) {
142
+ const database = await openSearchSessionDatabase();
143
+ try {
144
+ const now = Date.now();
145
+ const sessionId = createSearchSessionId(input);
146
+ const optionsJSON = JSON.stringify({
147
+ chapters: input.chapters,
148
+ order: input.order,
149
+ types: input.types
150
+ });
151
+ await database.transaction(async () => {
152
+ await deleteSearchSession(database, sessionId);
153
+ await database.run(
154
+ `
155
+ INSERT INTO search_sessions (
156
+ session_id, archive_key, query, options_json, terms_json, lens,
157
+ match, created_at, expires_at, accessed_at
158
+ )
159
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
160
+ `,
161
+ [
162
+ sessionId,
163
+ input.archiveKey,
164
+ input.query,
165
+ optionsJSON,
166
+ JSON.stringify(input.terms),
167
+ input.lens,
168
+ input.match,
169
+ now,
170
+ now + SEARCH_SESSION_TTL_MS,
171
+ now
172
+ ]
173
+ );
174
+ for (const [index, item] of (input.items ?? []).entries()) {
175
+ await database.run(
176
+ `
177
+ INSERT INTO search_results (session_id, rank, item_json)
178
+ VALUES (?, ?, ?)
179
+ `,
180
+ [sessionId, index, JSON.stringify(item)]
181
+ );
182
+ }
183
+ for (const event of input.evidenceEvents ?? []) {
184
+ await insertSearchEvidenceHitEvent(database, sessionId, event);
185
+ }
186
+ for (const hit of input.entityHits ?? []) {
187
+ await upsertSearchEntityHit(database, sessionId, hit);
188
+ }
189
+ for (const hit of input.tripleHits ?? []) {
190
+ await upsertSearchTripleHit(database, sessionId, hit);
191
+ }
192
+ for (const hit of input.chunkHits ?? []) {
193
+ await upsertSearchChunkHit(database, sessionId, hit);
194
+ }
195
+ });
196
+ return sessionId;
197
+ } finally {
198
+ await database.close();
199
+ }
200
+ }
201
+ async function readSearchSessionObjectBucketPage(sessionId, bucket, after, limit) {
202
+ const database = await openSearchSessionDatabase();
203
+ try {
204
+ const entityRows = await readSearchSessionEntityBucketRows(
205
+ database,
206
+ sessionId,
207
+ after,
208
+ limit + 1
209
+ );
210
+ const tripleRows = await readSearchSessionTripleBucketRows(
211
+ database,
212
+ sessionId,
213
+ after,
214
+ limit + 1
215
+ );
216
+ return [...entityRows, ...tripleRows].sort(compareObjectBucketHits).slice(0, limit + 1);
217
+ } finally {
218
+ await database.close();
219
+ }
220
+ }
221
+ async function readSearchSessionChunkBucketPage(sessionId, after, limit) {
222
+ const database = await openSearchSessionDatabase();
223
+ try {
224
+ return await database.queryAll(
225
+ `
226
+ SELECT
227
+ chunk_id,
228
+ result_score
229
+ FROM search_chunk_hits
230
+ WHERE session_id = ?
231
+ ${after === void 0 ? "" : `
232
+ AND (
233
+ result_score < ?
234
+ OR (result_score = ? AND chunk_id > ?)
235
+ )
236
+ `}
237
+ ORDER BY result_score DESC, chunk_id
238
+ LIMIT ?
239
+ `,
240
+ [
241
+ sessionId,
242
+ ...after === void 0 ? [] : [after.score, after.score, after.chunkId],
243
+ limit + 1
244
+ ],
245
+ (row) => {
246
+ const chunkId = getNumber(row, "chunk_id");
247
+ return {
248
+ field: "title",
249
+ id: `wikg://chunk/${chunkId}`,
250
+ score: getNumber(row, "result_score"),
251
+ snippet: `chunk ${chunkId}`,
252
+ title: `chunk ${chunkId}`,
253
+ type: "node"
254
+ };
255
+ }
256
+ );
257
+ } finally {
258
+ await database.close();
259
+ }
260
+ }
261
+ async function createEntitySearchSession(input) {
262
+ const database = await openSearchSessionDatabase();
263
+ try {
264
+ const now = Date.now();
265
+ const sessionId = createEntitySearchSessionId(input);
266
+ const optionsJSON = JSON.stringify({
267
+ chapters: input.chapters,
268
+ order: input.order,
269
+ types: input.types
270
+ });
271
+ await database.transaction(async () => {
272
+ await deleteSearchSession(database, sessionId);
273
+ await database.run(
274
+ `
275
+ INSERT INTO search_sessions (
276
+ session_id, archive_key, query, options_json, terms_json, lens,
277
+ match, created_at, expires_at, accessed_at
278
+ )
279
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
280
+ `,
281
+ [
282
+ sessionId,
283
+ input.archiveKey,
284
+ input.query,
285
+ optionsJSON,
286
+ JSON.stringify(input.terms),
287
+ input.lens,
288
+ input.match,
289
+ now,
290
+ now + SEARCH_SESSION_TTL_MS,
291
+ now
292
+ ]
293
+ );
294
+ for (const event of input.evidenceEvents ?? []) {
295
+ await insertSearchEvidenceHitEvent(database, sessionId, event);
296
+ }
297
+ for (const hit of input.entityHits ?? []) {
298
+ await upsertSearchEntityHit(database, sessionId, hit);
299
+ }
300
+ for (const hit of input.tripleHits ?? []) {
301
+ await upsertSearchTripleHit(database, sessionId, hit);
302
+ }
303
+ for (const hit of input.chunkHits ?? []) {
304
+ await upsertSearchChunkHit(database, sessionId, hit);
305
+ }
306
+ });
307
+ return sessionId;
308
+ } finally {
309
+ await database.close();
310
+ }
311
+ }
312
+ async function populateSearchSessionObjectCaches(input) {
313
+ const database = await openSearchSessionDatabase();
314
+ try {
315
+ await database.transaction(async () => {
316
+ for (const event of input.evidenceEvents ?? []) {
317
+ await insertSearchEvidenceHitEvent(database, input.sessionId, event);
318
+ }
319
+ for (const hit of input.entityHits ?? []) {
320
+ await upsertSearchEntityHit(database, input.sessionId, hit);
321
+ }
322
+ for (const hit of input.tripleHits ?? []) {
323
+ await upsertSearchTripleHit(database, input.sessionId, hit);
324
+ }
325
+ for (const hit of input.chunkHits ?? []) {
326
+ await upsertSearchChunkHit(database, input.sessionId, hit);
327
+ }
328
+ await database.run(
329
+ `
330
+ UPDATE search_sessions
331
+ SET object_caches_populated = 1
332
+ WHERE session_id = ?
333
+ `,
334
+ [input.sessionId]
335
+ );
336
+ });
337
+ } finally {
338
+ await database.close();
339
+ }
340
+ }
341
+ async function deleteArchiveSearchSessions(archiveKey) {
342
+ const database = await openSearchSessionDatabase();
343
+ try {
344
+ const sessionIds = await database.queryAll(
345
+ `
346
+ SELECT session_id
347
+ FROM search_sessions
348
+ WHERE archive_key = ?
349
+ `,
350
+ [archiveKey],
351
+ (row) => getString(row, "session_id")
352
+ );
353
+ await database.transaction(async () => {
354
+ for (const sessionId of sessionIds) {
355
+ await deleteSearchSession(database, sessionId);
356
+ }
357
+ await deleteUnusedPredicates(database);
358
+ });
359
+ } finally {
360
+ await database.close();
361
+ }
362
+ }
363
+ async function runSearchCacheGc(context) {
364
+ const databasePath = getSearchSessionDatabasePath();
365
+ const beforeBytes = await readFileSize(databasePath);
366
+ const database = await openSearchSessionDatabase();
367
+ try {
368
+ const scanned = await database.queryOne(
369
+ "SELECT COUNT(*) AS count FROM search_sessions",
370
+ void 0,
371
+ (row) => getNumber(row, "count")
372
+ );
373
+ const expiredSessionIds = context.force ? await listAllSearchSessionIds(database) : await listExpiredSearchSessionIds(database, context.now);
374
+ const prunedSessionIds = context.force ? [] : await listPrunedSearchSessionIds(database);
375
+ const sessionIds = [
376
+ .../* @__PURE__ */ new Set([...expiredSessionIds, ...prunedSessionIds])
377
+ ].sort();
378
+ if (!context.dryRun && sessionIds.length > 0) {
379
+ await database.transaction(async () => {
380
+ for (const sessionId of sessionIds) {
381
+ await deleteSearchSession(database, sessionId);
382
+ }
383
+ await deleteUnusedPredicates(database);
384
+ });
385
+ await database.run("VACUUM");
386
+ }
387
+ const afterBytes = await readFileSize(databasePath);
388
+ return {
389
+ freedBytes: Math.max(0, beforeBytes - afterBytes),
390
+ removed: sessionIds.length,
391
+ scanned: scanned ?? 0
392
+ };
393
+ } finally {
394
+ await database.close();
395
+ }
396
+ }
397
+ async function readSearchSessionPage(sessionId, offset, limit, expectedArchiveKey, expectedCreatedAt) {
398
+ const database = await openSearchSessionDatabase();
399
+ try {
400
+ const session = await readSearchSessionMetadata(
401
+ database,
402
+ sessionId,
403
+ expectedArchiveKey,
404
+ expectedCreatedAt
405
+ );
406
+ await touchSearchSession(database, sessionId);
407
+ const rows = await database.queryAll(
408
+ `
409
+ SELECT rank, item_json
410
+ FROM search_results
411
+ WHERE session_id = ? AND rank >= ?
412
+ ORDER BY rank
413
+ LIMIT ?
414
+ `,
415
+ [sessionId, offset, limit + 1],
416
+ (row) => ({
417
+ item: parseSearchResultItem(getString(row, "item_json")),
418
+ rank: getNumber(row, "rank")
419
+ })
420
+ );
421
+ const items = rows.slice(0, limit).map((row) => row.item);
422
+ const last = rows.at(limit - 1);
423
+ return {
424
+ chapters: session.options.chapters,
425
+ items,
426
+ lens: session.lens,
427
+ match: session.match,
428
+ nextCursor: rows.length > limit && last !== void 0 ? encodeSearchSessionCursor(
429
+ sessionId,
430
+ last.rank + 1,
431
+ session.createdAt
432
+ ) : null,
433
+ query: session.query,
434
+ sessionId,
435
+ terms: session.terms,
436
+ types: session.options.types
437
+ };
438
+ } finally {
439
+ await database.close();
440
+ }
441
+ }
442
+ async function readEntitySearchSessionPage(sessionId, offset, limit, expectedArchiveKey, expectedCreatedAt) {
443
+ const database = await openSearchSessionDatabase();
444
+ try {
445
+ const session = await readSearchSessionMetadata(
446
+ database,
447
+ sessionId,
448
+ expectedArchiveKey,
449
+ expectedCreatedAt
450
+ );
451
+ await touchSearchSession(database, sessionId);
452
+ const rows = await database.queryAll(
453
+ `
454
+ SELECT
455
+ qid,
456
+ result_score
457
+ FROM search_entity_hits
458
+ WHERE session_id = ?
459
+ ORDER BY result_score DESC, qid
460
+ LIMIT ? OFFSET ?
461
+ `,
462
+ [sessionId, limit + 1, offset],
463
+ mapEntitySearchObjectRow
464
+ );
465
+ const items = rows.slice(0, limit);
466
+ const nextOffset = offset + items.length;
467
+ return {
468
+ chapters: session.options.chapters,
469
+ items,
470
+ lens: session.lens,
471
+ match: session.match,
472
+ nextCursor: rows.length > limit ? encodeSearchSessionCursor(sessionId, nextOffset, session.createdAt) : null,
473
+ query: session.query,
474
+ sessionId,
475
+ terms: session.terms,
476
+ types: session.options.types
477
+ };
478
+ } finally {
479
+ await database.close();
480
+ }
481
+ }
482
+ async function readSearchSessionDescriptor(sessionId, expectedArchiveKey) {
483
+ const database = await openSearchSessionDatabase();
484
+ try {
485
+ const session = await readSearchSessionMetadata(
486
+ database,
487
+ sessionId,
488
+ expectedArchiveKey
489
+ );
490
+ await touchSearchSession(database, sessionId);
491
+ return {
492
+ chapters: session.options.chapters,
493
+ createdAt: session.createdAt,
494
+ lens: session.lens,
495
+ match: session.match,
496
+ objectCachesPopulated: session.objectCachesPopulated,
497
+ query: session.query,
498
+ sessionId,
499
+ terms: session.terms,
500
+ types: session.options.types
501
+ };
502
+ } finally {
503
+ await database.close();
504
+ }
505
+ }
506
+ async function readSearchSessionMetadataForCursor(sessionId, expectedArchiveKey, expectedCreatedAt) {
507
+ const database = await openSearchSessionDatabase();
508
+ try {
509
+ const session = await readSearchSessionMetadata(
510
+ database,
511
+ sessionId,
512
+ expectedArchiveKey,
513
+ expectedCreatedAt
514
+ );
515
+ await touchSearchSession(database, sessionId);
516
+ return {
517
+ chapters: session.options.chapters,
518
+ createdAt: session.createdAt,
519
+ lens: session.lens,
520
+ match: session.match,
521
+ objectCachesPopulated: session.objectCachesPopulated,
522
+ query: session.query,
523
+ sessionId,
524
+ terms: session.terms,
525
+ types: session.options.types
526
+ };
527
+ } finally {
528
+ await database.close();
529
+ }
530
+ }
531
+ async function readEntitySearchEvidenceMentions(sessionId, mentionIds, limit) {
532
+ if (mentionIds.length === 0) {
533
+ return [];
534
+ }
535
+ const database = await openSearchSessionDatabase();
536
+ try {
537
+ const placeholders = mentionIds.map(() => "?").join(", ");
538
+ return await database.queryAll(
539
+ `
540
+ SELECT
541
+ event.evidence_id AS mention_id,
542
+ event.score AS score
543
+ FROM search_evidence_hit_events AS event
544
+ WHERE event.session_id = ?
545
+ AND event.evidence_kind = ?
546
+ AND event.evidence_id IN (${placeholders})
547
+ ORDER BY event.score DESC, event.chapter_id, event.sentence_index,
548
+ event.evidence_id
549
+ LIMIT ?
550
+ `,
551
+ [sessionId, SEARCH_EVIDENCE_KIND.mention, ...mentionIds, limit],
552
+ (row) => ({
553
+ mentionId: getString(row, "mention_id"),
554
+ score: getNumber(row, "score")
555
+ })
556
+ );
557
+ } finally {
558
+ await database.close();
559
+ }
560
+ }
561
+ function encodeSearchSessionCursor(sessionId, offset, createdAt) {
562
+ return Buffer.from(
563
+ JSON.stringify({ createdAt, offset, sessionId, v: 3 })
564
+ ).toString("base64url");
565
+ }
566
+ function encodeBucketSearchSessionCursor(sessionId, cursor, createdAt) {
567
+ return Buffer.from(
568
+ JSON.stringify({ createdAt, cursor, sessionId, v: 4 })
569
+ ).toString("base64url");
570
+ }
571
+ function decodeBucketSearchSessionCursor(cursor) {
572
+ try {
573
+ const parsed = JSON.parse(
574
+ Buffer.from(cursor, "base64url").toString("utf8")
575
+ );
576
+ if (typeof parsed === "object" && parsed !== null && "createdAt" in parsed && "cursor" in parsed && "sessionId" in parsed && "v" in parsed && parsed.v === 4 && typeof parsed.createdAt === "number" && Number.isInteger(parsed.createdAt) && parsed.createdAt >= 0 && typeof parsed.sessionId === "string" && parsed.sessionId !== "" && isBucketSearchCursor(parsed.cursor)) {
577
+ return {
578
+ createdAt: parsed.createdAt,
579
+ cursor: parsed.cursor,
580
+ sessionId: parsed.sessionId
581
+ };
582
+ }
583
+ } catch {
584
+ throw new Error("Invalid search cursor.");
585
+ }
586
+ throw new Error("Invalid search cursor.");
587
+ }
588
+ function decodeSearchSessionCursor(cursor) {
589
+ try {
590
+ const parsed = JSON.parse(
591
+ Buffer.from(cursor, "base64url").toString("utf8")
592
+ );
593
+ if (typeof parsed === "object" && parsed !== null && "offset" in parsed && "sessionId" in parsed && "createdAt" in parsed && "v" in parsed && parsed.v === 3 && typeof parsed.sessionId === "string" && parsed.sessionId !== "" && typeof parsed.createdAt === "number" && Number.isInteger(parsed.createdAt) && parsed.createdAt >= 0 && typeof parsed.offset === "number" && Number.isInteger(parsed.offset) && parsed.offset >= 0) {
594
+ return {
595
+ createdAt: parsed.createdAt,
596
+ offset: parsed.offset,
597
+ sessionId: parsed.sessionId
598
+ };
599
+ }
600
+ if (typeof parsed === "object" && parsed !== null && "offset" in parsed && "sessionId" in parsed && "v" in parsed && parsed.v === 2 && typeof parsed.sessionId === "string" && parsed.sessionId !== "" && typeof parsed.offset === "number" && Number.isInteger(parsed.offset) && parsed.offset >= 0) {
601
+ return { offset: parsed.offset, sessionId: parsed.sessionId };
602
+ }
603
+ } catch {
604
+ throw new Error("Invalid search cursor.");
605
+ }
606
+ throw new Error("Invalid search cursor.");
607
+ }
608
+ async function openSearchSessionDatabase() {
609
+ return await openSharedStateDatabase(
610
+ getSearchSessionDatabasePath(),
611
+ SEARCH_SESSION_SCHEMA_SQL
612
+ );
613
+ }
614
+ function getSearchSessionDatabasePath() {
615
+ return join(getSearchSessionStateDirectoryPath(), "search-sessions.sqlite");
616
+ }
617
+ function getSearchSessionStateDirectoryPath() {
618
+ return resolveWikiGraphCacheDirectoryPath();
619
+ }
620
+ async function listExpiredSearchSessionIds(database, now) {
621
+ return await database.queryAll(
622
+ `
623
+ SELECT session_id
624
+ FROM search_sessions
625
+ WHERE expires_at < ?
626
+ `,
627
+ [now],
628
+ (row) => getString(row, "session_id")
629
+ );
630
+ }
631
+ async function listAllSearchSessionIds(database) {
632
+ return await database.queryAll(
633
+ "SELECT session_id FROM search_sessions",
634
+ void 0,
635
+ (row) => getString(row, "session_id")
636
+ );
637
+ }
638
+ async function hasSearchSession(sessionId, archiveKey) {
639
+ const database = await openSearchSessionDatabase();
640
+ try {
641
+ const row = await database.queryOne(
642
+ `
643
+ SELECT session_id
644
+ FROM search_sessions
645
+ WHERE session_id = ? AND archive_key = ?
646
+ AND expires_at >= ?
647
+ `,
648
+ [sessionId, archiveKey, Date.now()],
649
+ () => true
650
+ );
651
+ return row === true;
652
+ } finally {
653
+ await database.close();
654
+ }
655
+ }
656
+ async function deleteSearchSession(database, sessionId) {
657
+ await database.run("DELETE FROM search_results WHERE session_id = ?", [
658
+ sessionId
659
+ ]);
660
+ await database.run(
661
+ "DELETE FROM search_evidence_hit_events WHERE session_id = ?",
662
+ [sessionId]
663
+ );
664
+ await database.run("DELETE FROM search_entity_hits WHERE session_id = ?", [
665
+ sessionId
666
+ ]);
667
+ await database.run("DELETE FROM search_triple_hits WHERE session_id = ?", [
668
+ sessionId
669
+ ]);
670
+ await database.run("DELETE FROM search_chunk_hits WHERE session_id = ?", [
671
+ sessionId
672
+ ]);
673
+ await database.run("DELETE FROM search_sessions WHERE session_id = ?", [
674
+ sessionId
675
+ ]);
676
+ }
677
+ async function deleteUnusedPredicates(database) {
678
+ await database.run(`
679
+ DELETE FROM predicate_dictionary
680
+ WHERE NOT EXISTS (
681
+ SELECT 1
682
+ FROM search_triple_hits
683
+ WHERE search_triple_hits.predicate_id = predicate_dictionary.id
684
+ )
685
+ `);
686
+ }
687
+ async function insertSearchEvidenceHitEvent(database, sessionId, event) {
688
+ await database.run(
689
+ `
690
+ INSERT OR REPLACE INTO search_evidence_hit_events (
691
+ session_id,
692
+ evidence_kind,
693
+ evidence_id,
694
+ chapter_id,
695
+ sentence_index,
696
+ score
697
+ )
698
+ VALUES (?, ?, ?, ?, ?, ?)
699
+ `,
700
+ [
701
+ sessionId,
702
+ event.evidenceKind,
703
+ event.evidenceId,
704
+ event.chapterId,
705
+ event.sentenceIndex,
706
+ event.score
707
+ ]
708
+ );
709
+ }
710
+ async function upsertSearchEntityHit(database, sessionId, hit) {
711
+ const current = await database.queryOne(
712
+ `
713
+ SELECT property_top_scores_json, evidence_top_scores_json
714
+ FROM search_entity_hits
715
+ WHERE session_id = ? AND qid = ?
716
+ `,
717
+ [sessionId, hit.qid],
718
+ (row) => ({
719
+ evidenceTopScores: parseNumberArray(
720
+ getString(row, "evidence_top_scores_json")
721
+ ),
722
+ propertyTopScores: parseNumberArray(
723
+ getString(row, "property_top_scores_json")
724
+ )
725
+ })
726
+ );
727
+ const propertyTopScores = mergeTopScores(
728
+ current?.propertyTopScores ?? [],
729
+ hit.propertyTopScores ?? []
730
+ );
731
+ const evidenceTopScores = mergeTopScores(
732
+ current?.evidenceTopScores ?? [],
733
+ hit.evidenceTopScores ?? []
734
+ );
735
+ const propertyScore = aggregateCachedScores(propertyTopScores);
736
+ const evidenceScore = aggregateCachedScores(evidenceTopScores);
737
+ const resultScore = propertyScore + evidenceScore;
738
+ await database.run(
739
+ `
740
+ INSERT INTO search_entity_hits (
741
+ session_id,
742
+ qid,
743
+ property_top_scores_json,
744
+ evidence_top_scores_json,
745
+ property_score,
746
+ evidence_score,
747
+ result_score
748
+ )
749
+ VALUES (?, ?, ?, ?, ?, ?, ?)
750
+ ON CONFLICT(session_id, qid) DO UPDATE SET
751
+ property_top_scores_json = excluded.property_top_scores_json,
752
+ evidence_top_scores_json = excluded.evidence_top_scores_json,
753
+ property_score = excluded.property_score,
754
+ evidence_score = excluded.evidence_score,
755
+ result_score = excluded.result_score
756
+ `,
757
+ [
758
+ sessionId,
759
+ hit.qid,
760
+ JSON.stringify(propertyTopScores),
761
+ JSON.stringify(evidenceTopScores),
762
+ propertyScore,
763
+ evidenceScore,
764
+ resultScore
765
+ ]
766
+ );
767
+ }
768
+ async function upsertSearchTripleHit(database, sessionId, hit) {
769
+ const predicateId = await getOrCreatePredicateId(database, hit.predicate);
770
+ const current = await database.queryOne(
771
+ `
772
+ SELECT evidence_top_scores_json
773
+ FROM search_triple_hits
774
+ WHERE session_id = ?
775
+ AND subject_qid = ?
776
+ AND predicate_id = ?
777
+ AND object_qid = ?
778
+ `,
779
+ [sessionId, hit.subjectQid, predicateId, hit.objectQid],
780
+ (row) => ({
781
+ evidenceTopScores: parseNumberArray(
782
+ getString(row, "evidence_top_scores_json")
783
+ )
784
+ })
785
+ );
786
+ const evidenceTopScores = mergeTopScores(
787
+ current?.evidenceTopScores ?? [],
788
+ hit.evidenceTopScores
789
+ );
790
+ const resultScore = aggregateCachedScores(evidenceTopScores);
791
+ await database.run(
792
+ `
793
+ INSERT INTO search_triple_hits (
794
+ session_id,
795
+ subject_qid,
796
+ predicate_id,
797
+ object_qid,
798
+ evidence_top_scores_json,
799
+ result_score
800
+ )
801
+ VALUES (?, ?, ?, ?, ?, ?)
802
+ ON CONFLICT(session_id, subject_qid, predicate_id, object_qid)
803
+ DO UPDATE SET
804
+ evidence_top_scores_json = excluded.evidence_top_scores_json,
805
+ result_score = excluded.result_score
806
+ `,
807
+ [
808
+ sessionId,
809
+ hit.subjectQid,
810
+ predicateId,
811
+ hit.objectQid,
812
+ JSON.stringify(evidenceTopScores),
813
+ resultScore
814
+ ]
815
+ );
816
+ }
817
+ async function upsertSearchChunkHit(database, sessionId, hit) {
818
+ const current = await database.queryOne(
819
+ `
820
+ SELECT property_top_scores_json, evidence_top_scores_json
821
+ FROM search_chunk_hits
822
+ WHERE session_id = ? AND chunk_id = ?
823
+ `,
824
+ [sessionId, hit.chunkId],
825
+ (row) => ({
826
+ evidenceTopScores: parseNumberArray(
827
+ getString(row, "evidence_top_scores_json")
828
+ ),
829
+ propertyTopScores: parseNumberArray(
830
+ getString(row, "property_top_scores_json")
831
+ )
832
+ })
833
+ );
834
+ const propertyTopScores = mergeTopScores(
835
+ current?.propertyTopScores ?? [],
836
+ hit.propertyTopScores ?? []
837
+ );
838
+ const evidenceTopScores = mergeTopScores(
839
+ current?.evidenceTopScores ?? [],
840
+ hit.evidenceTopScores ?? []
841
+ );
842
+ const propertyScore = aggregateCachedScores(propertyTopScores);
843
+ const evidenceScore = aggregateCachedScores(evidenceTopScores);
844
+ const resultScore = propertyScore + evidenceScore;
845
+ await database.run(
846
+ `
847
+ INSERT INTO search_chunk_hits (
848
+ session_id,
849
+ chunk_id,
850
+ property_top_scores_json,
851
+ evidence_top_scores_json,
852
+ property_score,
853
+ evidence_score,
854
+ result_score
855
+ )
856
+ VALUES (?, ?, ?, ?, ?, ?, ?)
857
+ ON CONFLICT(session_id, chunk_id) DO UPDATE SET
858
+ property_top_scores_json = excluded.property_top_scores_json,
859
+ evidence_top_scores_json = excluded.evidence_top_scores_json,
860
+ property_score = excluded.property_score,
861
+ evidence_score = excluded.evidence_score,
862
+ result_score = excluded.result_score
863
+ `,
864
+ [
865
+ sessionId,
866
+ hit.chunkId,
867
+ JSON.stringify(propertyTopScores),
868
+ JSON.stringify(evidenceTopScores),
869
+ propertyScore,
870
+ evidenceScore,
871
+ resultScore
872
+ ]
873
+ );
874
+ }
875
+ async function getOrCreatePredicateId(database, predicate) {
876
+ await database.run(
877
+ `
878
+ INSERT OR IGNORE INTO predicate_dictionary(value)
879
+ VALUES (?)
880
+ `,
881
+ [predicate]
882
+ );
883
+ const id = await database.queryOne(
884
+ `
885
+ SELECT id
886
+ FROM predicate_dictionary
887
+ WHERE value = ?
888
+ `,
889
+ [predicate],
890
+ (row) => getNumber(row, "id")
891
+ );
892
+ if (id === void 0) {
893
+ throw new Error("Failed to create predicate dictionary entry.");
894
+ }
895
+ return id;
896
+ }
897
+ async function listPrunedSearchSessionIds(database) {
898
+ return await database.queryAll(
899
+ `
900
+ SELECT session_id
901
+ FROM search_sessions
902
+ ORDER BY accessed_at DESC, created_at DESC, session_id
903
+ LIMIT -1 OFFSET ?
904
+ `,
905
+ [SEARCH_SESSION_MAX_COUNT],
906
+ (row) => getString(row, "session_id")
907
+ );
908
+ }
909
+ async function readFileSize(path) {
910
+ try {
911
+ return (await stat(path)).size;
912
+ } catch (error) {
913
+ if (isNodeError(error) && error.code === "ENOENT") {
914
+ return 0;
915
+ }
916
+ throw error;
917
+ }
918
+ }
919
+ async function readSearchSessionMetadata(database, sessionId, expectedArchiveKey, expectedCreatedAt) {
920
+ const session = await database.queryOne(
921
+ `
922
+ SELECT
923
+ session_id,
924
+ query,
925
+ options_json,
926
+ terms_json,
927
+ lens,
928
+ match,
929
+ object_caches_populated,
930
+ created_at,
931
+ expires_at
932
+ FROM search_sessions
933
+ WHERE session_id = ?
934
+ ${expectedArchiveKey === void 0 ? "" : "AND archive_key = ?"}
935
+ ${expectedCreatedAt === void 0 ? "" : "AND created_at = ?"}
936
+ `,
937
+ [
938
+ sessionId,
939
+ ...expectedArchiveKey === void 0 ? [] : [expectedArchiveKey],
940
+ ...expectedCreatedAt === void 0 ? [] : [expectedCreatedAt]
941
+ ],
942
+ (row) => ({
943
+ createdAt: getNumber(row, "created_at"),
944
+ expiresAt: getNumber(row, "expires_at"),
945
+ lens: getString(row, "lens"),
946
+ match: getString(row, "match"),
947
+ objectCachesPopulated: getNumber(row, "object_caches_populated") !== 0,
948
+ options: parseSessionOptions(getString(row, "options_json")),
949
+ query: getString(row, "query"),
950
+ sessionId: getString(row, "session_id"),
951
+ terms: parseStringArray(getString(row, "terms_json"))
952
+ })
953
+ );
954
+ if (session === void 0 || session.expiresAt < Date.now()) {
955
+ throw new Error("Search cursor expired. Run the search again.");
956
+ }
957
+ return session;
958
+ }
959
+ async function touchSearchSession(database, sessionId) {
960
+ await database.run(
961
+ `
962
+ UPDATE search_sessions
963
+ SET accessed_at = ?, expires_at = ?
964
+ WHERE session_id = ?
965
+ `,
966
+ [Date.now(), Date.now() + SEARCH_SESSION_TTL_MS, sessionId]
967
+ );
968
+ }
969
+ function createEntitySearchSessionId(input) {
970
+ return createHash("sha256").update(
971
+ JSON.stringify({
972
+ archiveKey: input.archiveKey,
973
+ entity: true,
974
+ lens: input.lens,
975
+ match: input.match,
976
+ order: input.order,
977
+ rankingVersion: SEARCH_RANKING_VERSION,
978
+ revisionScope: input.revisionScope,
979
+ scope: normalizeSearchSessionScope(input.chapters),
980
+ terms: input.terms,
981
+ types: normalizeSearchSessionTypes(input.types)
982
+ })
983
+ ).digest("hex");
984
+ }
985
+ function mapEntitySearchObjectRow(row) {
986
+ const qid = getString(row, "qid");
987
+ return {
988
+ evidence: {
989
+ nextCursor: null,
990
+ shown: 0,
991
+ sources: [],
992
+ total: 0
993
+ },
994
+ field: "title",
995
+ id: `wikg://entity/${qid}`,
996
+ score: getNumber(row, "result_score"),
997
+ snippet: qid,
998
+ title: qid,
999
+ type: "entity"
1000
+ };
1001
+ }
1002
+ async function readSearchSessionEntityBucketRows(database, sessionId, after, limit) {
1003
+ return await database.queryAll(
1004
+ `
1005
+ SELECT
1006
+ qid,
1007
+ result_score
1008
+ FROM search_entity_hits
1009
+ WHERE session_id = ?
1010
+ ${after === void 0 ? "" : `
1011
+ AND (
1012
+ result_score < ?
1013
+ OR (
1014
+ result_score = ?
1015
+ AND (
1016
+ ? < ?
1017
+ OR (? = ? AND qid > ?)
1018
+ )
1019
+ )
1020
+ )
1021
+ `}
1022
+ ORDER BY result_score DESC, qid
1023
+ LIMIT ?
1024
+ `,
1025
+ [
1026
+ sessionId,
1027
+ ...after === void 0 ? [] : [
1028
+ after.score,
1029
+ after.score,
1030
+ getObjectBucketKindOrder(after.kind),
1031
+ SEARCH_OBJECT_BUCKET_KIND.entity,
1032
+ getObjectBucketKindOrder(after.kind),
1033
+ SEARCH_OBJECT_BUCKET_KIND.entity,
1034
+ after.id
1035
+ ],
1036
+ limit
1037
+ ],
1038
+ mapEntitySearchObjectRow
1039
+ );
1040
+ }
1041
+ async function readSearchSessionTripleBucketRows(database, sessionId, after, limit) {
1042
+ return await database.queryAll(
1043
+ `
1044
+ SELECT
1045
+ search_triple_hits.subject_qid AS subject_qid,
1046
+ predicate_dictionary.value AS predicate,
1047
+ search_triple_hits.object_qid AS object_qid,
1048
+ search_triple_hits.result_score AS result_score
1049
+ FROM search_triple_hits
1050
+ JOIN predicate_dictionary
1051
+ ON predicate_dictionary.id = search_triple_hits.predicate_id
1052
+ WHERE search_triple_hits.session_id = ?
1053
+ ${after === void 0 ? "" : `
1054
+ AND (
1055
+ search_triple_hits.result_score < ?
1056
+ OR (
1057
+ search_triple_hits.result_score = ?
1058
+ AND (
1059
+ ? < ?
1060
+ OR (
1061
+ ? = ?
1062
+ AND (
1063
+ search_triple_hits.subject_qid || char(31) ||
1064
+ predicate_dictionary.value || char(31) ||
1065
+ search_triple_hits.object_qid
1066
+ ) > ?
1067
+ )
1068
+ )
1069
+ )
1070
+ )
1071
+ `}
1072
+ ORDER BY search_triple_hits.result_score DESC,
1073
+ search_triple_hits.subject_qid,
1074
+ predicate_dictionary.value,
1075
+ search_triple_hits.object_qid
1076
+ LIMIT ?
1077
+ `,
1078
+ [
1079
+ sessionId,
1080
+ ...after === void 0 ? [] : [
1081
+ after.score,
1082
+ after.score,
1083
+ getObjectBucketKindOrder(after.kind),
1084
+ SEARCH_OBJECT_BUCKET_KIND.triple,
1085
+ getObjectBucketKindOrder(after.kind),
1086
+ SEARCH_OBJECT_BUCKET_KIND.triple,
1087
+ after.id
1088
+ ],
1089
+ limit
1090
+ ],
1091
+ (row) => {
1092
+ const subjectQid = getString(row, "subject_qid");
1093
+ const predicate = getString(row, "predicate");
1094
+ const objectQid = getString(row, "object_qid");
1095
+ const title = `${subjectQid} ${predicate} ${objectQid}`;
1096
+ return {
1097
+ field: "content",
1098
+ id: `wikg://triple/${subjectQid}/${encodeURIComponent(predicate)}/${objectQid}`,
1099
+ score: getNumber(row, "result_score"),
1100
+ snippet: title,
1101
+ title,
1102
+ triple: {
1103
+ objectLabel: objectQid,
1104
+ predicate,
1105
+ subjectLabel: subjectQid
1106
+ },
1107
+ type: "triple"
1108
+ };
1109
+ }
1110
+ );
1111
+ }
1112
+ function compareObjectBucketHits(left, right) {
1113
+ return (right.score ?? 0) - (left.score ?? 0) || getObjectBucketKindOrder(getObjectBucketHitKind(left)) - getObjectBucketKindOrder(getObjectBucketHitKind(right)) || getObjectBucketHitKey(left).localeCompare(getObjectBucketHitKey(right));
1114
+ }
1115
+ const SEARCH_OBJECT_BUCKET_KIND = {
1116
+ entity: 1,
1117
+ triple: 2
1118
+ };
1119
+ function getObjectBucketHitKind(hit) {
1120
+ return hit.type === "triple" ? "triple" : "entity";
1121
+ }
1122
+ function getObjectBucketHitKey(hit) {
1123
+ if (hit.type !== "triple") {
1124
+ return hit.id.slice("wikg://entity/".length);
1125
+ }
1126
+ return [
1127
+ hit.triple?.subjectLabel ?? "",
1128
+ hit.triple?.predicate ?? "",
1129
+ hit.triple?.objectLabel ?? ""
1130
+ ].join("");
1131
+ }
1132
+ function getObjectBucketKindOrder(kind) {
1133
+ return SEARCH_OBJECT_BUCKET_KIND[kind];
1134
+ }
1135
+ function isBucketSearchCursor(value) {
1136
+ if (typeof value !== "object" || value === null || !("bucket" in value)) {
1137
+ return false;
1138
+ }
1139
+ const cursor = value;
1140
+ switch (cursor.bucket) {
1141
+ case 0:
1142
+ return cursor.key === void 0 || isChapterTitleCursorKey(cursor.key);
1143
+ case 1:
1144
+ return cursor.key === void 0 || isObjectCursorKey(cursor.key);
1145
+ case 2:
1146
+ return cursor.key === void 0 || isChunkCursorKey(cursor.key);
1147
+ case 3:
1148
+ return cursor.key === void 0 || isTextCursorKey(cursor.key);
1149
+ default:
1150
+ return false;
1151
+ }
1152
+ }
1153
+ function isChapterTitleCursorKey(value) {
1154
+ return typeof value === "object" && value !== null && typeof value.chapterId === "number" && typeof value.score === "number";
1155
+ }
1156
+ function isObjectCursorKey(value) {
1157
+ return typeof value === "object" && value !== null && typeof value.id === "string" && (value.kind === "entity" || value.kind === "triple") && typeof value.score === "number";
1158
+ }
1159
+ function isChunkCursorKey(value) {
1160
+ return typeof value === "object" && value !== null && typeof value.chunkId === "number" && typeof value.score === "number";
1161
+ }
1162
+ function isTextCursorKey(value) {
1163
+ return typeof value === "object" && value !== null && typeof value.chapterId === "number" && typeof value.kind === "number" && typeof value.rank === "number" && typeof value.sentenceIndex === "number";
1164
+ }
1165
+ function createSearchSessionId(input) {
1166
+ return createHash("sha256").update(
1167
+ JSON.stringify({
1168
+ archiveKey: input.archiveKey,
1169
+ entity: false,
1170
+ lens: input.lens,
1171
+ match: input.match,
1172
+ order: input.order,
1173
+ rankingVersion: SEARCH_RANKING_VERSION,
1174
+ revisionScope: input.revisionScope,
1175
+ scope: normalizeSearchSessionScope(input.chapters),
1176
+ terms: input.terms,
1177
+ types: normalizeSearchSessionTypes(input.types)
1178
+ })
1179
+ ).digest("hex");
1180
+ }
1181
+ function normalizeSearchSessionScope(chapters) {
1182
+ return chapters === null ? null : [...new Set(chapters)].sort(compareNumbers);
1183
+ }
1184
+ function normalizeSearchSessionTypes(types) {
1185
+ return types === null ? null : [...new Set(types)].sort();
1186
+ }
1187
+ function compareNumbers(left, right) {
1188
+ return left - right;
1189
+ }
1190
+ function parseSearchResultItem(value) {
1191
+ const parsed = JSON.parse(value);
1192
+ if (typeof parsed !== "object" || parsed === null) {
1193
+ throw new Error("Invalid cached search result.");
1194
+ }
1195
+ return parsed;
1196
+ }
1197
+ function parseSessionOptions(value) {
1198
+ const parsed = JSON.parse(value);
1199
+ if (typeof parsed === "object" && parsed !== null && "chapters" in parsed && "types" in parsed && (parsed.chapters === null || Array.isArray(parsed.chapters) && parsed.chapters.every((chapter) => typeof chapter === "number")) && (parsed.types === null || Array.isArray(parsed.types) && parsed.types.every((type) => typeof type === "string"))) {
1200
+ return {
1201
+ chapters: parsed.chapters,
1202
+ types: parsed.types
1203
+ };
1204
+ }
1205
+ throw new Error("Invalid cached search session.");
1206
+ }
1207
+ function parseStringArray(value) {
1208
+ const parsed = JSON.parse(value);
1209
+ if (Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
1210
+ return parsed;
1211
+ }
1212
+ throw new Error("Invalid cached search session.");
1213
+ }
1214
+ function parseNumberArray(value) {
1215
+ const parsed = JSON.parse(value);
1216
+ if (Array.isArray(parsed) && parsed.every((item) => typeof item === "number" && Number.isFinite(item))) {
1217
+ return parsed.map((item) => Number(item));
1218
+ }
1219
+ return [];
1220
+ }
1221
+ function mergeTopScores(current, incoming) {
1222
+ return [...current, ...incoming].filter((score) => Number.isFinite(score)).sort((left, right) => right - left).slice(0, SEARCH_TOP_SCORE_COUNT);
1223
+ }
1224
+ function aggregateCachedScores(scores) {
1225
+ return scores.slice(0, SEARCH_TOP_SCORE_COUNT).reduce((total, score, index) => total + score / Math.log2(index + 2), 0);
1226
+ }
1227
+ export {
1228
+ SEARCH_EVIDENCE_KIND,
1229
+ createEntitySearchSession,
1230
+ createSearchSession,
1231
+ decodeBucketSearchSessionCursor,
1232
+ decodeSearchSessionCursor,
1233
+ deleteArchiveSearchSessions,
1234
+ encodeBucketSearchSessionCursor,
1235
+ encodeSearchSessionCursor,
1236
+ populateSearchSessionObjectCaches,
1237
+ readCachedEntitySearchSessionPage,
1238
+ readCachedSearchSessionPage,
1239
+ readEntitySearchEvidenceMentions,
1240
+ readEntitySearchSessionPage,
1241
+ readSearchSessionChunkBucketPage,
1242
+ readSearchSessionDescriptor,
1243
+ readSearchSessionMetadataForCursor,
1244
+ readSearchSessionObjectBucketPage,
1245
+ readSearchSessionPage,
1246
+ runSearchCacheGc
1247
+ };
1248
+ //# sourceMappingURL=search-cache.js.map