@harperfast/harper 5.3.0-beta.4 → 5.3.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.
Files changed (314) hide show
  1. package/bin/backup.ts +6 -1
  2. package/components/Application.ts +486 -115
  3. package/components/DESIGN.md +109 -21
  4. package/components/deploymentProvenance.ts +28 -0
  5. package/components/operations.js +14 -7
  6. package/components/packageComponent.ts +5 -1
  7. package/config-root.schema.json +1 -1
  8. package/dataLayer/DESIGN.md +35 -7
  9. package/dataLayer/blobBackup.ts +71 -30
  10. package/dataLayer/harperBridge/ResourceBridge.ts +16 -2
  11. package/dataLayer/rocksdbBackup.ts +88 -34
  12. package/dataLayer/schemaDescribe.ts +45 -1
  13. package/dist/bin/backup.js +1 -1
  14. package/dist/bin/backup.js.map +1 -1
  15. package/dist/components/Application.d.ts +11 -21
  16. package/dist/components/Application.js +436 -105
  17. package/dist/components/Application.js.map +1 -1
  18. package/dist/components/deploymentProvenance.d.ts +4 -0
  19. package/dist/components/deploymentProvenance.js +32 -0
  20. package/dist/components/deploymentProvenance.js.map +1 -0
  21. package/dist/components/operations.js +14 -7
  22. package/dist/components/operations.js.map +1 -1
  23. package/dist/components/packageComponent.js +6 -1
  24. package/dist/components/packageComponent.js.map +1 -1
  25. package/dist/dataLayer/blobBackup.d.ts +30 -3
  26. package/dist/dataLayer/blobBackup.js +73 -36
  27. package/dist/dataLayer/blobBackup.js.map +1 -1
  28. package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +1 -0
  29. package/dist/dataLayer/harperBridge/ResourceBridge.js +15 -3
  30. package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
  31. package/dist/dataLayer/rocksdbBackup.d.ts +4 -1
  32. package/dist/dataLayer/rocksdbBackup.js +74 -36
  33. package/dist/dataLayer/rocksdbBackup.js.map +1 -1
  34. package/dist/dataLayer/schemaDescribe.js +45 -1
  35. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  36. package/dist/resources/DatabaseTransaction.d.ts +1 -0
  37. package/dist/resources/DatabaseTransaction.js +33 -8
  38. package/dist/resources/DatabaseTransaction.js.map +1 -1
  39. package/dist/resources/ResourceInterface.d.ts +7 -3
  40. package/dist/resources/ResourceInterface.js +2 -0
  41. package/dist/resources/ResourceInterface.js.map +1 -1
  42. package/dist/resources/Table.d.ts +151 -445
  43. package/dist/resources/Table.js +209 -8
  44. package/dist/resources/Table.js.map +1 -1
  45. package/dist/resources/analytics/write.d.ts +11 -0
  46. package/dist/resources/analytics/write.js +3 -0
  47. package/dist/resources/analytics/write.js.map +1 -1
  48. package/dist/resources/blob.d.ts +30 -0
  49. package/dist/resources/blob.js +189 -1
  50. package/dist/resources/blob.js.map +1 -1
  51. package/dist/resources/databases.d.ts +1 -0
  52. package/dist/resources/databases.js +80 -15
  53. package/dist/resources/databases.js.map +1 -1
  54. package/dist/resources/derivedIndexRuntime.d.ts +13 -0
  55. package/dist/resources/derivedIndexRuntime.js +57 -5
  56. package/dist/resources/derivedIndexRuntime.js.map +1 -1
  57. package/dist/resources/derivedIndexes.d.ts +1 -0
  58. package/dist/resources/derivedIndexes.js +116 -15
  59. package/dist/resources/derivedIndexes.js.map +1 -1
  60. package/dist/resources/fullTextSchema.d.ts +5 -3
  61. package/dist/resources/fullTextSchema.js +48 -5
  62. package/dist/resources/fullTextSchema.js.map +1 -1
  63. package/dist/resources/fullTextSchemaLifecycle.d.ts +2 -0
  64. package/dist/resources/fullTextSchemaLifecycle.js +33 -0
  65. package/dist/resources/fullTextSchemaLifecycle.js.map +1 -1
  66. package/dist/resources/graphql.js +30 -12
  67. package/dist/resources/graphql.js.map +1 -1
  68. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +21 -1
  69. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +114 -5
  70. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  71. package/dist/resources/indexes/fullTextDerivedIndex.d.ts +11 -2
  72. package/dist/resources/indexes/fullTextDerivedIndex.js +187 -24
  73. package/dist/resources/indexes/fullTextDerivedIndex.js.map +1 -1
  74. package/dist/resources/indexes/fullTextNativeBinding.d.ts +99 -1
  75. package/dist/resources/indexes/fullTextNativeBinding.js +35 -1
  76. package/dist/resources/indexes/fullTextNativeBinding.js.map +1 -1
  77. package/dist/resources/indexes/fullTextQueryIndex.d.ts +58 -0
  78. package/dist/resources/indexes/fullTextQueryIndex.js +943 -0
  79. package/dist/resources/indexes/fullTextQueryIndex.js.map +1 -0
  80. package/dist/resources/indexes/fullTextQueryProtocol.d.ts +6 -0
  81. package/dist/resources/indexes/fullTextQueryProtocol.js +32 -0
  82. package/dist/resources/indexes/fullTextQueryProtocol.js.map +1 -0
  83. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.d.ts +4 -1
  84. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js +30 -7
  85. package/dist/resources/indexes/nativeFullTextDerivedIndexLifecycle.js.map +1 -1
  86. package/dist/resources/search.d.ts +41 -0
  87. package/dist/resources/search.js +468 -26
  88. package/dist/resources/search.js.map +1 -1
  89. package/dist/resources/transactionBroadcast.js +101 -50
  90. package/dist/resources/transactionBroadcast.js.map +1 -1
  91. package/dist/resources/typeParity.d.ts +9 -0
  92. package/dist/resources/typeParity.js +3 -0
  93. package/dist/resources/typeParity.js.map +1 -0
  94. package/dist/server/REST.js.map +1 -1
  95. package/dist/server/itc/serverHandlers.js +48 -8
  96. package/dist/server/itc/serverHandlers.js.map +1 -1
  97. package/dist/server/serverHelpers/contentTypes.d.ts +7 -0
  98. package/dist/server/serverHelpers/contentTypes.js +36 -23
  99. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  100. package/dist/server/serverHelpers/uwsServer.js +28 -5
  101. package/dist/server/serverHelpers/uwsServer.js.map +1 -1
  102. package/dist/server/threads/itc.js +19 -0
  103. package/dist/server/threads/itc.js.map +1 -1
  104. package/dist/server/threads/manageThreads.d.ts +3 -0
  105. package/dist/server/threads/manageThreads.js +90 -23
  106. package/dist/server/threads/manageThreads.js.map +1 -1
  107. package/dist/utility/operation_authorization.js +25 -7
  108. package/dist/utility/operation_authorization.js.map +1 -1
  109. package/dist/utility/signalling.js +3 -0
  110. package/dist/utility/signalling.js.map +1 -1
  111. package/dist/validation/searchValidator.js +22 -2
  112. package/dist/validation/searchValidator.js.map +1 -1
  113. package/npm-shrinkwrap.json +22 -22
  114. package/package.json +2 -4
  115. package/resources/DESIGN.md +19 -2
  116. package/resources/DatabaseTransaction.ts +40 -10
  117. package/resources/FULL_TEXT.md +97 -0
  118. package/resources/ResourceInterface.ts +8 -2
  119. package/resources/Table.ts +767 -17
  120. package/resources/analytics/write.ts +3 -3
  121. package/resources/blob.ts +183 -1
  122. package/resources/databases.ts +126 -14
  123. package/resources/derivedIndexRuntime.ts +79 -6
  124. package/resources/derivedIndexes.ts +142 -18
  125. package/resources/fullTextSchema.ts +55 -9
  126. package/resources/fullTextSchemaLifecycle.ts +45 -0
  127. package/resources/graphql.ts +33 -12
  128. package/resources/indexes/DESIGN.md +167 -15
  129. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +125 -5
  130. package/resources/indexes/fullTextDerivedIndex.ts +216 -32
  131. package/resources/indexes/fullTextNativeBinding.ts +133 -3
  132. package/resources/indexes/fullTextQueryIndex.ts +1120 -0
  133. package/resources/indexes/fullTextQueryProtocol.ts +35 -0
  134. package/resources/indexes/nativeFullTextDerivedIndexLifecycle.ts +28 -8
  135. package/resources/search.ts +513 -26
  136. package/resources/transactionBroadcast.ts +86 -47
  137. package/resources/typeParity.ts +20 -0
  138. package/schema.graphql +18 -5
  139. package/server/DESIGN.md +18 -0
  140. package/server/REST.ts +1 -1
  141. package/server/itc/serverHandlers.js +61 -8
  142. package/server/serverHelpers/contentTypes.ts +31 -26
  143. package/server/serverHelpers/uwsServer.ts +35 -7
  144. package/server/threads/itc.js +21 -0
  145. package/server/threads/manageThreads.js +95 -21
  146. package/studio/web/assets/{Chat-Bq60AO-g.js → Chat-CNEKMllJ.js} +13 -13
  147. package/studio/web/assets/FloatingChat-CEnWhHeR.js +23 -0
  148. package/studio/web/assets/SearchDialog-CwhJdEdY.js +1 -0
  149. package/studio/web/assets/{abnfDiagram-O67JEVCF-DpPZWMOf.js → abnfDiagram-O67JEVCF-raXE027J.js} +1 -1
  150. package/studio/web/assets/alertDialog-BbWD9Xxa.js +1 -0
  151. package/studio/web/assets/apiToken-DC5vsaaO.js +1 -0
  152. package/studio/web/assets/applications-DQZxDy0x.js +296 -0
  153. package/studio/web/assets/architecture-7GRP2DOG-DDmz3hpI.js +1 -0
  154. package/studio/web/assets/{architectureDiagram-NJMV4G6O-OmgLraID.js → architectureDiagram-NJMV4G6O-C8_Eet7w.js} +1 -1
  155. package/studio/web/assets/arrow-up-D2g_57vT.js +1 -0
  156. package/studio/web/assets/authStore-CJCaADw9.js +3 -0
  157. package/studio/web/assets/{blockDiagram-BEXU5L5S-Cv7CD3Ai.js → blockDiagram-BEXU5L5S-DR6S5-1D.js} +1 -1
  158. package/studio/web/assets/{button-MFP9n8Ck.js → button-DWwfgGWI.js} +2 -2
  159. package/studio/web/assets/{c4Diagram-YGBWAQC7-Ds1vKYnN.js → c4Diagram-YGBWAQC7-BAfZ1G01.js} +1 -1
  160. package/studio/web/assets/channel-D0AkPjJ8.js +1 -0
  161. package/studio/web/assets/{chevron-up-CFe8x5Bp.js → chevron-up-CFxbMGv2.js} +1 -1
  162. package/studio/web/assets/{chunk-3FUC2YCW-DpnBPH8B.js → chunk-3FUC2YCW-DuRp-j19.js} +1 -1
  163. package/studio/web/assets/{chunk-5DYCD2WN-LLLCQSzg.js → chunk-5DYCD2WN-BceBfIHT.js} +1 -1
  164. package/studio/web/assets/{chunk-742MDFTN-BL8J_pIO.js → chunk-742MDFTN-CIkt8ijt.js} +1 -1
  165. package/studio/web/assets/{chunk-7INBJB4K-C-hJHiiK.js → chunk-7INBJB4K-BpeAXyOi.js} +1 -1
  166. package/studio/web/assets/{chunk-7M6MHVWA-C6ZqkFbA.js → chunk-7M6MHVWA-h6WlaTzO.js} +1 -1
  167. package/studio/web/assets/{chunk-7PRAP22T-CUXM8BG6.js → chunk-7PRAP22T-KyqX6x3f.js} +1 -1
  168. package/studio/web/assets/{chunk-GTNCS2PH-DJ2BFvS1.js → chunk-GTNCS2PH-DGHLXyow.js} +1 -1
  169. package/studio/web/assets/{chunk-GWA4HPMP-C42bSqLL.js → chunk-GWA4HPMP-DsejB6gA.js} +1 -1
  170. package/studio/web/assets/{chunk-MBY4JIJT-C-5jz6Lo.js → chunk-MBY4JIJT-BwSGweQP.js} +1 -1
  171. package/studio/web/assets/{chunk-NETBCI7D-D-bzlN4r.js → chunk-NETBCI7D-C8UnOw_f.js} +1 -1
  172. package/studio/web/assets/{chunk-O7XYJQB3-ep14zA23.js → chunk-O7XYJQB3-CBS3nZYV.js} +1 -1
  173. package/studio/web/assets/{chunk-UA2S7LBM-BMRWRHED.js → chunk-UA2S7LBM-BHpEdH8D.js} +1 -1
  174. package/studio/web/assets/{chunk-WEXAMYUT-DdLYVdX1.js → chunk-WEXAMYUT-BAIhTwyh.js} +1 -1
  175. package/studio/web/assets/{chunk-Z7XXMR3K-BmKEDjcP.js → chunk-Z7XXMR3K-DSHbImdf.js} +1 -1
  176. package/studio/web/assets/{chunk-ZIGJFQKS-DLZgdNxA.js → chunk-ZIGJFQKS-Cs8fUn7y.js} +1 -1
  177. package/studio/web/assets/{classDiagram-v2-NBCMYWYE-DOI5vgKT.js → classDiagram-v2-NBCMYWYE-DmDPkt2u.js} +1 -1
  178. package/studio/web/assets/cn-6T8VranJ.js +1 -0
  179. package/studio/web/assets/{codicon-Brq4_Ui5.ttf → codicon-DF1abBS2.ttf} +0 -0
  180. package/studio/web/assets/{createLucideIcon-bziYxJli.js → createLucideIcon-fO5dL7D5.js} +1 -1
  181. package/studio/web/assets/{css.worker-l1psR_wG.js → css.worker-DoT-OOzx.js} +36 -36
  182. package/studio/web/assets/{cssMode-DJyc9mHj.js → cssMode-Dz2DxF4e.js} +1 -1
  183. package/studio/web/assets/{cynefin-OW5HDTMX-BSW-DB7S.js → cynefin-OW5HDTMX-DIvbXLSj.js} +1 -1
  184. package/studio/web/assets/{cynefinDiagram-VND7K2PF-CbAHEwxt.js → cynefinDiagram-VND7K2PF-BdtaXiCE.js} +1 -1
  185. package/studio/web/assets/{dagre-6A5THRUB-Csxewgs4.js → dagre-6A5THRUB-C7RUWHyz.js} +1 -1
  186. package/studio/web/assets/{diagram-22UHCM2B-a0rt8tY4.js → diagram-22UHCM2B-DJCvcaWP.js} +1 -1
  187. package/studio/web/assets/{diagram-3UASUU5V-lEj2SVNh.js → diagram-3UASUU5V-Du6VKWln.js} +1 -1
  188. package/studio/web/assets/{diagram-ATOU4E4O-HcrAeB-q.js → diagram-ATOU4E4O-dxRfeG4B.js} +1 -1
  189. package/studio/web/assets/{diagram-CDSNMT55-CYxiuyEx.js → diagram-CDSNMT55-l5Ga0u-W.js} +1 -1
  190. package/studio/web/assets/{diagram-MLGK6HIB-ChbCJTgJ.js → diagram-MLGK6HIB-CNQY47LA.js} +1 -1
  191. package/studio/web/assets/{diagram-MPIPVDR6-DaX9Y-N3.js → diagram-MPIPVDR6-7prveD1B.js} +1 -1
  192. package/studio/web/assets/{dist-Cz2Y6-6G.js → dist-BrRuMUzt.js} +1 -1
  193. package/studio/web/assets/{download-CtostjYn.js → download-Cn6tPG4L.js} +1 -1
  194. package/studio/web/assets/{ebnfDiagram-ZINNZB2B-CwAsENB1.js → ebnfDiagram-ZINNZB2B-5OnkTpfi.js} +1 -1
  195. package/studio/web/assets/{editor-DDIsQfj6.js → editor-B3mjd3tz.js} +1 -1
  196. package/studio/web/assets/editor.worker-Yd1NR0QT.js +33 -0
  197. package/studio/web/assets/{elk-276RUBZZ-Hexg9E4D.js → elk-276RUBZZ-DxDQPjQT.js} +1 -1
  198. package/studio/web/assets/{erDiagram-OPXOYQCR-CeC-wwO1.js → erDiagram-OPXOYQCR-CQlCX84D.js} +1 -1
  199. package/studio/web/assets/eventmodeling-NTZA5JFV-DONQf5aG.js +1 -0
  200. package/studio/web/assets/flowDiagram-KWPJA3E3-BoZ8_QR1.js +1 -0
  201. package/studio/web/assets/{ganttDiagram-FUAMR5RP-C2_Hhl1-.js → ganttDiagram-FUAMR5RP-bloX3Voy.js} +1 -1
  202. package/studio/web/assets/{getAnalytics-CjthMQqF.js → getAnalytics-C0FHjtdQ.js} +1 -1
  203. package/studio/web/assets/{gitGraph-4MIJSDKK-xIk5Vuew.js → gitGraph-4MIJSDKK-BrXWmJt2.js} +1 -1
  204. package/studio/web/assets/{gitGraphDiagram-X574FWY7-CMxJ34up.js → gitGraphDiagram-X574FWY7-C2KnnZeY.js} +1 -1
  205. package/studio/web/assets/{html-g1BJHxLy.js → html-BsRGM7tp.js} +1 -1
  206. package/studio/web/assets/{html.worker-DdwM4IrA.js → html.worker-B1dwY0Ay.js} +27 -27
  207. package/studio/web/assets/{htmlMode-Vh5IglCQ.js → htmlMode-tUKJaA3o.js} +1 -1
  208. package/studio/web/assets/index-72cEH474.css +1 -0
  209. package/studio/web/assets/index-BuqFjN5K.js +828 -0
  210. package/studio/web/assets/index.lazy-CcpfQFY_.js +2 -0
  211. package/studio/web/assets/{info-A6RAGUB7-o49TEbj-.js → info-A6RAGUB7-BhzBHe4U.js} +1 -1
  212. package/studio/web/assets/{infoDiagram-VRGFBTTK-Cjhh7yzZ.js → infoDiagram-VRGFBTTK-B0J1132p.js} +1 -1
  213. package/studio/web/assets/{ishikawaDiagram-OU5B5YK6-C63aXRmh.js → ishikawaDiagram-OU5B5YK6-BNk0tuQx.js} +1 -1
  214. package/studio/web/assets/{javascript-5VIolqf7.js → javascript-BZ_uRGHl.js} +1 -1
  215. package/studio/web/assets/{journeyDiagram-ZHPQQLJL-D_o0P5Mu.js → journeyDiagram-ZHPQQLJL-Be79RMQM.js} +1 -1
  216. package/studio/web/assets/json.worker-BQqXGI3X.js +65 -0
  217. package/studio/web/assets/{jsonMode-DG4zQraI.js → jsonMode-DgB-aFMj.js} +1 -1
  218. package/studio/web/assets/{kanban-definition-PNTS6WVX-CTI9SSxY.js → kanban-definition-PNTS6WVX-4uuoQP9W.js} +1 -1
  219. package/studio/web/assets/{languageServices-t5FBpX-i.js → languageServices-BleuBw17.js} +1 -1
  220. package/studio/web/assets/localStorageKeys-etzFY_xV.js +1 -0
  221. package/studio/web/assets/{lspLanguageFeatures-DgVnNPh-.js → lspLanguageFeatures-ByVYLSsQ.js} +1 -1
  222. package/studio/web/assets/{mermaid-parser.core-C2lcH_jP.js → mermaid-parser.core-V1UYMeXV.js} +3 -3
  223. package/studio/web/assets/{mermaid.core-BG5bjfIG.js → mermaid.core-1PX6R49U.js} +4 -4
  224. package/studio/web/assets/{mindmap-definition-NLK3R4M7-BK7ho6JD.js → mindmap-definition-NLK3R4M7-C70Ctm0J.js} +1 -1
  225. package/studio/web/assets/notifications-D1Nf-Edn.js +1 -0
  226. package/studio/web/assets/notifications-TuzN0IMi.js +1 -0
  227. package/studio/web/assets/{packet-AYTQ26CC-BHPy6KBV.js → packet-AYTQ26CC-DWbXHx5g.js} +1 -1
  228. package/studio/web/assets/{pegDiagram-GJSIUBJH-DzjwG3jO.js → pegDiagram-GJSIUBJH-d6z1cc7W.js} +1 -1
  229. package/studio/web/assets/{pie-WAS4IAKB-D0cP-DTU.js → pie-WAS4IAKB-DjoTm3yr.js} +1 -1
  230. package/studio/web/assets/{pieDiagram-5QR66LMP-C_hOP9Lv.js → pieDiagram-5QR66LMP-Dz3RHpDA.js} +1 -1
  231. package/studio/web/assets/profile-D7C7Lupz.js +1 -0
  232. package/studio/web/assets/{quadrantDiagram-O4NWA36T-CZW8PbV1.js → quadrantDiagram-O4NWA36T-CIF5Qkou.js} +1 -1
  233. package/studio/web/assets/{radar-RG4KPBEZ-C8fk0U81.js → radar-RG4KPBEZ-CVBgjCOj.js} +1 -1
  234. package/studio/web/assets/{railroad-74A4TZTK-B60FWm17.js → railroad-74A4TZTK-BdhXw10Q.js} +1 -1
  235. package/studio/web/assets/railroad-abnf-HS5TGJTU-BcoQPN39.js +1 -0
  236. package/studio/web/assets/railroad-ebnf-LZEXJU2U-B1Lke2JN.js +1 -0
  237. package/studio/web/assets/railroad-peg-WCYAUIDC-D-oJFkiV.js +1 -0
  238. package/studio/web/assets/{railroadDiagram-XR7U4H2S-DyyNmgbU.js → railroadDiagram-XR7U4H2S-y3Jv2U6N.js} +1 -1
  239. package/studio/web/assets/regions-nGQCm-v8.js +1 -0
  240. package/studio/web/assets/register-C3x9Ze6P.js +909 -0
  241. package/studio/web/assets/register-DjpsE8to.css +1 -0
  242. package/studio/web/assets/{requirementDiagram-PLB6GJNP-C4H-mLKu.js → requirementDiagram-PLB6GJNP-ChINZEmu.js} +1 -1
  243. package/studio/web/assets/restartGate-nHAFLDh-.js +1 -0
  244. package/studio/web/assets/{sankeyDiagram-IPEJSGJF-DHDyga4c.js → sankeyDiagram-IPEJSGJF-D9AyLce2.js} +1 -1
  245. package/studio/web/assets/{sequenceDiagram-PO4LG4MO-CdNcHXRI.js → sequenceDiagram-PO4LG4MO-hfk4aIEm.js} +1 -1
  246. package/studio/web/assets/{setComponentFile-z4-qJCbA.js → setComponentFile-DpjrRqeG.js} +1 -1
  247. package/studio/web/assets/{setup-CS50uJ4x.js → setup-CGiKLZ9e.js} +2 -2
  248. package/studio/web/assets/{stateDiagram-v2-GCMORJYK-CpKuXq15.js → stateDiagram-v2-GCMORJYK-Bs8RIb9K.js} +1 -1
  249. package/studio/web/assets/status-CGJwrNPH.js +61 -0
  250. package/studio/web/assets/{swimlanes-2SLR337P-NRHa2D8I.js → swimlanes-2SLR337P-B52xrf6t.js} +1 -1
  251. package/studio/web/assets/swimlanesDiagram-TC7HE7FX-DfN7BAP5.js +8 -0
  252. package/studio/web/assets/tabs-BCTQzoQK.js +1 -0
  253. package/studio/web/assets/{timeline-definition-EJHVYXUP-D39Y-xpq.js → timeline-definition-EJHVYXUP-DJSITpQX.js} +1 -1
  254. package/studio/web/assets/toggleHighContrast-C-Ne6P7T.js +51 -0
  255. package/studio/web/assets/toggleHighContrast-n7clI0si.css +1 -0
  256. package/studio/web/assets/{treeView-Q6P3EWNA-CRWR9OqD.js → treeView-Q6P3EWNA-C-epdxRo.js} +1 -1
  257. package/studio/web/assets/{treemap-WGGIJYW6-ZfXyJgLO.js → treemap-WGGIJYW6-DOVyp_zw.js} +1 -1
  258. package/studio/web/assets/{ts.worker-DDMUrpqh.js → ts.worker-Clm12uY6.js} +131 -131
  259. package/studio/web/assets/{tsMode-D83Gg3cq.js → tsMode-CSreYTys.js} +1 -1
  260. package/studio/web/assets/{typescript-Dfp-GrNq.js → typescript-MnxBk89W.js} +1 -1
  261. package/studio/web/assets/{useEntityRestURL-BKetlINf.js → useEntityRestURL-TNrh77-s.js} +1 -1
  262. package/studio/web/assets/{usecaseDiagram-POWQR4AR-jf-zIDZ_.js → usecaseDiagram-POWQR4AR-B6252cbq.js} +1 -1
  263. package/studio/web/assets/{vendor-core-BdkdbUek.js → vendor-core-6LhfJlRC.js} +1 -1
  264. package/studio/web/assets/vendor-datadog-ozKf-pts.js +6 -0
  265. package/studio/web/assets/{vendor-react-izWchTRL.js → vendor-react-BOliS0BL.js} +1 -1
  266. package/studio/web/assets/vendor-tanstack-Bntfka-M.js +2 -0
  267. package/studio/web/assets/vendor-ui-9EYYDgoN.js +41 -0
  268. package/studio/web/assets/{vennDiagram-UO4OBE2U-BKYAZUh_.js → vennDiagram-UO4OBE2U-DZTsDA4k.js} +1 -1
  269. package/studio/web/assets/{wardley-WFR3VGLG-BO7f36ci.js → wardley-WFR3VGLG-Cfqoe6z4.js} +1 -1
  270. package/studio/web/assets/{wardleyDiagram-VNRHLVJA-Djb0JDQc.js → wardleyDiagram-VNRHLVJA-qu_f7Tvl.js} +1 -1
  271. package/studio/web/assets/{workers-CCvmDLH3.js → workers-BfZlUNVI.js} +3 -3
  272. package/studio/web/assets/{xml-06pZp00U.js → xml-BHd6qGH7.js} +1 -1
  273. package/studio/web/assets/{xychartDiagram-PMCCYNJV-BQh9ubvb.js → xychartDiagram-PMCCYNJV-UrOKRsmR.js} +1 -1
  274. package/studio/web/assets/{yaml-iSnWMVlV.js → yaml-C53R8OQq.js} +1 -1
  275. package/studio/web/assets/{yaml.worker-DAK2o_H1.js → yaml.worker-D9JekGdp.js} +183 -183
  276. package/studio/web/index.html +15 -15
  277. package/utility/operation_authorization.ts +27 -7
  278. package/utility/signalling.ts +3 -0
  279. package/validation/searchValidator.ts +22 -13
  280. package/studio/web/assets/FloatingChat-D4560T0p.js +0 -23
  281. package/studio/web/assets/alertDialog-UrbiMgQt.js +0 -1
  282. package/studio/web/assets/apiToken-BEvbFPMc.js +0 -1
  283. package/studio/web/assets/applications-CSUVTH4E.js +0 -296
  284. package/studio/web/assets/architecture-7GRP2DOG-11l4Ny1l.js +0 -1
  285. package/studio/web/assets/authStore-5jSS5pTW.js +0 -3
  286. package/studio/web/assets/channel-BDtouPd6.js +0 -1
  287. package/studio/web/assets/dialog-DTepachC.js +0 -1
  288. package/studio/web/assets/editor.worker-CkkvdXvO.js +0 -33
  289. package/studio/web/assets/eventmodeling-NTZA5JFV-CFb03e0o.js +0 -1
  290. package/studio/web/assets/flowDiagram-KWPJA3E3-Cidi00_Y.js +0 -1
  291. package/studio/web/assets/index-CPoDzQTe.css +0 -1
  292. package/studio/web/assets/index-DGRAzvO4.js +0 -824
  293. package/studio/web/assets/index.lazy-vgSic7et.js +0 -2
  294. package/studio/web/assets/json.worker-CSi2hF-a.js +0 -65
  295. package/studio/web/assets/notifications-BeWcX04m.js +0 -1
  296. package/studio/web/assets/notifications-DUGWrWoO.js +0 -1
  297. package/studio/web/assets/profile-BvUEDBzW.js +0 -1
  298. package/studio/web/assets/railroad-abnf-HS5TGJTU-CLMVZvH0.js +0 -1
  299. package/studio/web/assets/railroad-ebnf-LZEXJU2U--tlwFoVB.js +0 -1
  300. package/studio/web/assets/railroad-peg-WCYAUIDC-Dpuslblm.js +0 -1
  301. package/studio/web/assets/regions-CB-_2m7M.js +0 -1
  302. package/studio/web/assets/register-1w1Zr3b2.js +0 -848
  303. package/studio/web/assets/register-jjEx9u7D.css +0 -1
  304. package/studio/web/assets/setLocalStorage-D_kflv4U.js +0 -1
  305. package/studio/web/assets/status-CI0wOdOE.js +0 -61
  306. package/studio/web/assets/swimlanesDiagram-TC7HE7FX-BBk4t4hO.js +0 -8
  307. package/studio/web/assets/tabs-CnQ_zenf.js +0 -1
  308. package/studio/web/assets/toggleHighContrast--ixms01u.css +0 -1
  309. package/studio/web/assets/toggleHighContrast-BsAE4jPe.js +0 -49
  310. package/studio/web/assets/useLocalStorage-BYoZF60G.js +0 -1
  311. package/studio/web/assets/vendor-datadog-fCQhBHGk.js +0 -6
  312. package/studio/web/assets/vendor-tanstack-CQ1aRjVa.js +0 -2
  313. package/studio/web/assets/vendor-ui-aE1tHcW7.js +0 -41
  314. package/studio/web/assets/x-vYntCxm4.js +0 -1
@@ -0,0 +1,943 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FullTextQueryIndex = exports.fullTextComparatorMode = exports.FULL_TEXT_QUERY_RESUME_OPERATION = exports.FULL_TEXT_QUERY_PAUSE_OPERATION = void 0;
4
+ exports.pauseNativeFullTextQueryReaders = pauseNativeFullTextQueryReaders;
5
+ exports.resumeNativeFullTextQueryReaders = resumeNativeFullTextQueryReaders;
6
+ const node_crypto_1 = require("node:crypto");
7
+ const ordered_binary_1 = require("ordered-binary");
8
+ const hdbError_ts_1 = require("../../utility/errors/hdbError.js");
9
+ const derivedIndexRuntime_ts_1 = require("../derivedIndexRuntime.js");
10
+ const fullTextNativeBinding_ts_1 = require("./fullTextNativeBinding.js");
11
+ const nativeFullTextDerivedIndexLifecycle_ts_1 = require("./nativeFullTextDerivedIndexLifecycle.js");
12
+ const fullTextDerivedIndex_ts_1 = require("./fullTextDerivedIndex.js");
13
+ const fullTextQueryProtocol_ts_1 = require("./fullTextQueryProtocol.js");
14
+ var fullTextQueryProtocol_ts_2 = require("./fullTextQueryProtocol.js");
15
+ Object.defineProperty(exports, "FULL_TEXT_QUERY_PAUSE_OPERATION", { enumerable: true, get: function () { return fullTextQueryProtocol_ts_2.FULL_TEXT_QUERY_PAUSE_OPERATION; } });
16
+ Object.defineProperty(exports, "FULL_TEXT_QUERY_RESUME_OPERATION", { enumerable: true, get: function () { return fullTextQueryProtocol_ts_2.FULL_TEXT_QUERY_RESUME_OPERATION; } });
17
+ Object.defineProperty(exports, "fullTextComparatorMode", { enumerable: true, get: function () { return fullTextQueryProtocol_ts_2.fullTextComparatorMode; } });
18
+ const hnswDerivedIndex_ts_1 = require("./hnswDerivedIndex.js");
19
+ const logger_ts_1 = require("../../utility/logging/logger.js");
20
+ const RAW_PAGE_SIZE = 256;
21
+ const MIN_RAW_PAGE_SIZE = 32;
22
+ const RAW_PAGE_OVERFETCH_FACTOR = 2;
23
+ const MAX_RELOAD_FAILURES_BEFORE_REOPEN = 3;
24
+ const HIGHLIGHT_BLOB_READ_TIMEOUT_MILLISECONDS = 5_000;
25
+ const READER_DRAIN_GRACE_MILLISECONDS = 1_000;
26
+ const UTF8_DECODER = new TextDecoder('utf-8', { fatal: true });
27
+ const logger = (0, logger_ts_1.loggerWithTag)('fulltext-query-index');
28
+ class FullTextReaderPublicationError extends Error {
29
+ }
30
+ const queryIndexesByPath = new Map();
31
+ const pausedQueryPaths = new Map();
32
+ const retiredReadinessIdsByPath = new Map();
33
+ const MAX_RETIRED_READINESS_IDS_PER_PATH = 64;
34
+ class FullTextQueryIndex {
35
+ filteredSearch = true;
36
+ filePrimary = true;
37
+ #options;
38
+ #nativeOptions;
39
+ #definition;
40
+ #definitionSnapshot;
41
+ #configurationRevision = 0;
42
+ #binding;
43
+ #readerSlot;
44
+ #readerOperation;
45
+ #retiredReaderSlots = new Set();
46
+ #maxSearchWindow;
47
+ #maxAutocompleteResults;
48
+ #maxSearchBudgetMilliseconds;
49
+ #maxTraceRecords;
50
+ #maxTraceSourceBytes;
51
+ #closed = false;
52
+ #pauses = new Map();
53
+ #foreignPausesObservedBeforeReady = new Map();
54
+ #derivedHost;
55
+ #derivedHostReady = Promise.withResolvers();
56
+ #publicationSubscription;
57
+ #publicationRebuildRequested = false;
58
+ #refreshFailureWarned = false;
59
+ #unexpectedSearchFailureWarned = false;
60
+ constructor(options) {
61
+ this.#options = options;
62
+ this.#definition = options.definition;
63
+ this.#definitionSnapshot = queryDefinitionSnapshot(options.definition);
64
+ this.#nativeOptions = {
65
+ path: (0, nativeFullTextDerivedIndexLifecycle_ts_1.nativeFullTextIndexPath)(options.storePath, options.storeName),
66
+ indexId: options.indexId,
67
+ generation: digestGeneration(options.sourceGeneration),
68
+ fields: options.definition.fields.map(({ name, weight }) => ({ name, weight })),
69
+ analyzer: options.definition.analyzer,
70
+ stopWords: options.definition.stopWords,
71
+ positions: options.definition.positions,
72
+ surfaceTerms: options.definition.surfaceTerms,
73
+ synonyms: options.definition.synonyms.map(({ source, replacements }) => ({
74
+ source,
75
+ replacements: [...replacements],
76
+ })),
77
+ limits: { ...options.limits },
78
+ };
79
+ let indexes = queryIndexesByPath.get(this.#nativeOptions.path);
80
+ if (!indexes)
81
+ queryIndexesByPath.set(this.#nativeOptions.path, (indexes = new Set()));
82
+ indexes.add(this);
83
+ const retiredReadinessIds = retiredReadinessIdsByPath.get(this.#nativeOptions.path);
84
+ if (retiredReadinessIds?.delete(options.readinessId) && retiredReadinessIds.size === 0)
85
+ retiredReadinessIdsByPath.delete(this.#nativeOptions.path);
86
+ const pauses = pausedQueryPaths.get(this.#nativeOptions.path);
87
+ if (pauses) {
88
+ this.#pauses = new Map(pauses);
89
+ if ((0, derivedIndexRuntime_ts_1.readDerivedIndexReadiness)(options.auditStore, options.readinessId).state !== 'ready')
90
+ for (const [readinessId, ownerEpoch] of pauses)
91
+ if (readinessId !== options.readinessId)
92
+ this.#foreignPausesObservedBeforeReady.set(readinessId, ownerEpoch);
93
+ }
94
+ }
95
+ updateDefinition(definition) {
96
+ const snapshot = queryDefinitionSnapshot(definition);
97
+ if (snapshot === this.#definitionSnapshot)
98
+ return;
99
+ this.#definition = definition;
100
+ this.#definitionSnapshot = snapshot;
101
+ this.#nativeOptions.fields = definition.fields.map(({ name, weight }) => ({ name, weight }));
102
+ this.#configurationRevision++;
103
+ }
104
+ estimateCount() {
105
+ const store = this.#options.Table.primaryStore;
106
+ const records = typeof store.getEstimatedKeyCount === 'function' ? store.getEstimatedKeyCount() : store.getStats?.().entryCount;
107
+ return Math.max(1, Math.round((Number.isFinite(records) ? records : 20) * 0.05));
108
+ }
109
+ search(condition, context, options = {}) {
110
+ const maxIndexLagMilliseconds = condition.maxIndexLagMilliseconds ?? hnswDerivedIndex_ts_1.DEFAULT_MAX_INDEX_LAG_MILLISECONDS;
111
+ const waitForIndexMilliseconds = condition.waitForIndexMilliseconds ?? 0;
112
+ assertFreshnessOptions(maxIndexLagMilliseconds, waitForIndexMilliseconds);
113
+ const waiting = waitForIndexMilliseconds > 0;
114
+ let coverage;
115
+ const execute = async () => {
116
+ assertReady((0, derivedIndexRuntime_ts_1.readDerivedIndexReadiness)(this.#options.auditStore, this.#options.readinessId), this.#definition.name);
117
+ if (waiting) {
118
+ await context?.indexSearchStart;
119
+ context?.signal?.throwIfAborted();
120
+ const waitDeadline = performance.now() + waitForIndexMilliseconds;
121
+ const started = (0, derivedIndexRuntime_ts_1.derivedIndexTime)(this.#options.Table.primaryStore.rootStore);
122
+ let host = this.#derivedHost;
123
+ if (!host) {
124
+ const remaining = waitDeadline - performance.now();
125
+ if (remaining <= 0)
126
+ throw new hdbError_ts_1.DerivedIndexLagError('Timed out waiting for the local full-text query host; retry this query');
127
+ host = await this.#waitForDerivedHost(remaining, context?.signal);
128
+ }
129
+ const state = host?.readiness().state;
130
+ if (state !== 'ready')
131
+ throw new hdbError_ts_1.ServerError(`Full-text index '${this.#definition.name}' is ${state === 'unavailable' ? 'unavailable' : 'rebuilding'}`, 503);
132
+ context?.signal?.throwIfAborted();
133
+ if (options.minResults === 0) {
134
+ this.#unexpectedSearchFailureWarned = false;
135
+ return [];
136
+ }
137
+ if (this.#readCoverage(0).state !== 'current') {
138
+ await host.waitForCoverage(started, Math.max(0, waitDeadline - performance.now()), context?.signal);
139
+ }
140
+ context?.signal?.throwIfAborted();
141
+ const result = await this.#search(condition, context, options);
142
+ this.#unexpectedSearchFailureWarned = false;
143
+ return result;
144
+ }
145
+ coverage = this.#queryCoverage(maxIndexLagMilliseconds);
146
+ const result = await this.#search(condition, context, options);
147
+ this.#unexpectedSearchFailureWarned = false;
148
+ return result;
149
+ };
150
+ const operation = execute().catch((error) => {
151
+ if (error === context?.signal?.reason)
152
+ throw error;
153
+ if (nativeErrorNeedsRebuild(error)) {
154
+ this.#requestRebuild();
155
+ void this.#retireAllReaders().catch(() => undefined);
156
+ }
157
+ const publicError = publicSearchError(error, this.#definition.name);
158
+ if (publicError !== error &&
159
+ publicError instanceof hdbError_ts_1.ServerError &&
160
+ publicError.statusCode === 500 &&
161
+ !this.#unexpectedSearchFailureWarned) {
162
+ this.#unexpectedSearchFailureWarned = true;
163
+ logger.error?.(`Unexpected full-text search failure on '${this.#definition.name}'`, error);
164
+ }
165
+ throw publicError;
166
+ });
167
+ if (!waiting && coverage)
168
+ Object.defineProperty(operation, 'indexCoverage', { value: coverage });
169
+ operation.catch(() => { });
170
+ return operation;
171
+ }
172
+ attachDerivedHost(host) {
173
+ this.#derivedHost = host;
174
+ this.#derivedHostReady.resolve(host);
175
+ }
176
+ async #waitForDerivedHost(timeout, signal) {
177
+ signal?.throwIfAborted();
178
+ let timer;
179
+ let abort;
180
+ const unavailable = new Promise((_resolve, reject) => {
181
+ timer = setTimeout(() => reject(new hdbError_ts_1.DerivedIndexLagError('Timed out waiting for the local full-text query host; retry this query')), timeout);
182
+ if (signal) {
183
+ abort = () => reject(signal.reason ?? new Error('Index wait aborted'));
184
+ signal.addEventListener('abort', abort, { once: true });
185
+ }
186
+ });
187
+ try {
188
+ return await Promise.race([this.#derivedHostReady.promise, unavailable]);
189
+ }
190
+ finally {
191
+ clearTimeout(timer);
192
+ if (abort)
193
+ signal.removeEventListener('abort', abort);
194
+ }
195
+ }
196
+ async close() {
197
+ this.#closed = true;
198
+ const publicationSubscription = this.#publicationSubscription;
199
+ this.#publicationSubscription = undefined;
200
+ publicationSubscription?.close();
201
+ const retirement = this.#retireAllReaders();
202
+ void retirement.then(() => this.#unregister(), () => this.#unregister());
203
+ await withTimeout(retirement, (this.#maxSearchBudgetMilliseconds ?? 30_000) + READER_DRAIN_GRACE_MILLISECONDS, () => new hdbError_ts_1.ServerError('Full-text reader drain did not settle before timeout', 503));
204
+ }
205
+ async pause(readinessId, ownerEpoch) {
206
+ const current = this.#pauses.get(readinessId);
207
+ if (current !== undefined && current > ownerEpoch)
208
+ return;
209
+ if (current !== ownerEpoch) {
210
+ logger.info?.(`Pausing full-text readers for '${this.#definition.name}' while '${readinessId}' resets at owner epoch ${ownerEpoch}`);
211
+ if (readinessId !== this.#options.readinessId &&
212
+ (0, derivedIndexRuntime_ts_1.readDerivedIndexReadiness)(this.#options.auditStore, this.#options.readinessId).state !== 'ready')
213
+ this.#foreignPausesObservedBeforeReady.set(readinessId, ownerEpoch);
214
+ else
215
+ this.#foreignPausesObservedBeforeReady.delete(readinessId);
216
+ }
217
+ this.#pauses.set(readinessId, ownerEpoch);
218
+ await this.#retireAllReaders();
219
+ }
220
+ resume(readinessId, ownerEpoch) {
221
+ if (!this.#closed && this.#pauses.get(readinessId) === ownerEpoch) {
222
+ this.#pauses.delete(readinessId);
223
+ this.#foreignPausesObservedBeforeReady.delete(readinessId);
224
+ }
225
+ }
226
+ async #search(condition, context, options) {
227
+ const readiness = (0, derivedIndexRuntime_ts_1.readDerivedIndexReadiness)(this.#options.auditStore, this.#options.readinessId);
228
+ assertReady(readiness, this.#definition.name);
229
+ if (!this.#derivedHost)
230
+ throw new hdbError_ts_1.IndexRebuildingError(`Full-text index '${this.#definition.name}' is not ready`);
231
+ if (options.minResults === 0)
232
+ return [];
233
+ const publicationGeneration = this.#publicationRevision();
234
+ const acquisitionTimeout = Math.min(hnswDerivedIndex_ts_1.MAX_WAIT_FOR_INDEX_MILLISECONDS, Math.max(1, condition.waitForIndexMilliseconds ?? hnswDerivedIndex_ts_1.MAX_WAIT_FOR_INDEX_MILLISECONDS));
235
+ const acquisition = this.#acquireReader(readiness.ownerEpoch, publicationGeneration);
236
+ let abortListener;
237
+ const abort = context?.signal
238
+ ? new Promise((_resolve, reject) => {
239
+ abortListener = () => reject(context.signal.reason ?? new Error('Full-text search aborted'));
240
+ if (context.signal.aborted)
241
+ abortListener();
242
+ else
243
+ context.signal.addEventListener('abort', abortListener, { once: true });
244
+ })
245
+ : undefined;
246
+ let lease;
247
+ try {
248
+ lease = await withTimeout(abort ? Promise.race([acquisition, abort]) : acquisition, acquisitionTimeout, () => new hdbError_ts_1.ServerError('Full-text reader acquisition exceeded the index-wait budget', 503));
249
+ }
250
+ catch (error) {
251
+ void acquisition.then((orphaned) => orphaned.release(), () => { });
252
+ throw error;
253
+ }
254
+ finally {
255
+ if (abortListener)
256
+ context.signal.removeEventListener('abort', abortListener);
257
+ }
258
+ const reader = lease.reader;
259
+ try {
260
+ const deadline = performance.now() + this.#maxSearchBudgetMilliseconds;
261
+ const maxSearchWindow = this.#maxSearchWindow;
262
+ const query = condition.fullTextQuery ?? leafExpression(condition);
263
+ const autocomplete = expressionUsesAutocomplete(query);
264
+ const searchWindow = autocomplete ? this.#maxAutocompleteResults : maxSearchWindow;
265
+ const bounded = options.minResults !== undefined;
266
+ const target = bounded ? Math.max(1, options.minResults) : searchWindow;
267
+ if (target > searchWindow)
268
+ throw new hdbError_ts_1.ClientError(`Full-text query exceeds the ${searchWindow}-result ${autocomplete ? 'autocomplete ' : ''}search window; reduce offset or limit`, 400);
269
+ const accepted = [];
270
+ let offset = 0;
271
+ let moreMayExist = false;
272
+ let staleVersionHits = 0;
273
+ let expiredHits = 0;
274
+ const transaction = context && this.#options.Table._readTxnForContext(context);
275
+ while (accepted.length < target && offset < searchWindow) {
276
+ if (context?.signal?.aborted)
277
+ throw context.signal.reason ?? new Error('Full-text search aborted');
278
+ const desiredPageSize = bounded
279
+ ? Math.max(MIN_RAW_PAGE_SIZE, (target - accepted.length) * RAW_PAGE_OVERFETCH_FACTOR)
280
+ : RAW_PAGE_SIZE;
281
+ const limit = autocomplete ? searchWindow : Math.min(RAW_PAGE_SIZE, desiredPageSize, searchWindow - offset);
282
+ const result = await reader.search({
283
+ query,
284
+ offset,
285
+ limit,
286
+ ...(!bounded && offset === 0 ? { exactTotal: true } : null),
287
+ }, { remainingBudgetMilliseconds: remainingSearchBudget(deadline) });
288
+ if (!bounded && !autocomplete && result.totalRelation === 'exact' && result.total > searchWindow)
289
+ throw new hdbError_ts_1.ClientError(`Full-text query exceeds the ${searchWindow}-result search window; add a limit`, 400);
290
+ moreMayExist =
291
+ result.totalRelation === 'exact' ? offset + result.hits.length < result.total : result.hits.length === limit;
292
+ if (result.hits.length === 0)
293
+ break;
294
+ for (const hit of result.hits) {
295
+ const key = decodeNativeId(hit.id, this.#options.Table.tableId);
296
+ options.assertTransactionActive?.();
297
+ const entry = this.#options.Table.primaryStore.getEntry(key, { transaction });
298
+ if (typeof hit.version !== 'string')
299
+ throw new hdbError_ts_1.ServerError('Full-text index returned a hit without a source version', 500);
300
+ if (!entry?.value || hit.version !== String(entry.version)) {
301
+ staleVersionHits++;
302
+ continue;
303
+ }
304
+ if (this.#options.Table.isFullTextSearchEntryCurrent?.(entry) === false) {
305
+ staleVersionHits++;
306
+ continue;
307
+ }
308
+ if (entry.expiresAt !== undefined && entry.expiresAt < Date.now()) {
309
+ expiredHits++;
310
+ continue;
311
+ }
312
+ if (options.filter && !options.filter(key, entry))
313
+ continue;
314
+ accepted.push({ key, $score: hit.score, nativeId: hit.id, record: entry.value, recordEntry: entry });
315
+ if (accepted.length >= target)
316
+ break;
317
+ }
318
+ offset += result.hits.length;
319
+ if (autocomplete)
320
+ break;
321
+ if (!moreMayExist)
322
+ break;
323
+ if (accepted.length < target)
324
+ await new Promise((resolve) => setImmediate(resolve));
325
+ }
326
+ if (!bounded && moreMayExist)
327
+ throw new hdbError_ts_1.ClientError(`Full-text query exceeds the ${searchWindow}-result search window; add a limit`, 400);
328
+ if (bounded && accepted.length < target && moreMayExist && staleVersionHits > 0)
329
+ throw new hdbError_ts_1.DerivedIndexLagError(`Full-text index '${this.#definition.name}' changed while searching; retry this query`);
330
+ if (bounded && accepted.length < target && moreMayExist)
331
+ throw new hdbError_ts_1.ClientError(expiredHits > 0
332
+ ? `Expired full-text matches exhausted the ${searchWindow}-result search window; retry after index cleanup or narrow the query`
333
+ : `Full-text filters exhausted the ${searchWindow}-result search window; narrow the query or reduce offset`, 400);
334
+ if (condition.includeHighlights && accepted.length > 0)
335
+ await this.#addHighlights(reader, lease.definition, condition, accepted.slice(options.resultOffset ?? 0), deadline);
336
+ return accepted.map((entry) => ({
337
+ key: entry.key,
338
+ $score: entry.$score,
339
+ loadedEntry: entry.recordEntry,
340
+ ...(entry.$highlights ? { $highlights: entry.$highlights } : null),
341
+ }));
342
+ }
343
+ finally {
344
+ await lease.release();
345
+ }
346
+ }
347
+ async #addHighlights(reader, definition, condition, entries, deadline) {
348
+ const highlighting = definition.highlighting;
349
+ if (!highlighting)
350
+ return;
351
+ const highlightFields = new Set(definition.fields.filter((field) => field.highlight === true).map((field) => field.name));
352
+ if (highlightFields.size === 0)
353
+ return;
354
+ const leaves = (condition.fullTextLeaves ?? [leafDescriptor(condition)]).map((leaf) => ({
355
+ ...leaf,
356
+ fields: leaf.fields?.filter((field) => highlightFields.has(field)) ?? [...highlightFields],
357
+ }));
358
+ const byId = new Map(entries.map((entry) => [entry.nativeId, entry]));
359
+ const leafGroups = new Map();
360
+ for (const leaf of leaves) {
361
+ if (leaf.fields.length === 0)
362
+ continue;
363
+ const key = JSON.stringify([...leaf.fields].sort());
364
+ let group = leafGroups.get(key);
365
+ if (!group) {
366
+ const selected = new Set(leaf.fields);
367
+ const fields = definition.fields.map(({ name }) => name).filter((name) => selected.has(name));
368
+ leafGroups.set(key, (group = { fields, leaves: [] }));
369
+ }
370
+ group.leaves.push(leaf);
371
+ }
372
+ for (const { fields, leaves: fieldLeaves } of leafGroups.values()) {
373
+ const leafFields = new Set(fields);
374
+ for (const sourceEntries of traceEntryBatches(entries, definition, leafFields, this.#maxTraceRecords, this.#maxTraceSourceBytes)) {
375
+ const records = await Promise.all(sourceEntries.map(async ({ nativeId, record }) => ({
376
+ id: nativeId,
377
+ fields: await sourceFields(record, definition, leafFields, deadline),
378
+ })));
379
+ for (const leaf of fieldLeaves) {
380
+ for (const traceRecords of traceSourceBatches(records, this.#maxTraceSourceBytes)) {
381
+ const traced = await reader.traceMatches({ text: leaf.text, mode: leaf.mode, fields }, traceRecords, {
382
+ remainingBudgetMilliseconds: remainingSearchBudget(deadline),
383
+ snippets: true,
384
+ fragmentLength: highlighting.fragmentLength,
385
+ maxFragmentsPerValue: highlighting.maxFragments,
386
+ });
387
+ if (!traced.complete)
388
+ throw new hdbError_ts_1.ServerError('Full-text index returned incomplete highlights', 500);
389
+ for (const record of traced.records) {
390
+ const entry = byId.get(record.id);
391
+ if (!entry)
392
+ continue;
393
+ const highlights = (entry.$highlights ??= Object.create(null));
394
+ for (const value of record.values) {
395
+ if (!leafFields.has(value.field))
396
+ continue;
397
+ const values = (highlights[value.field] ??= []);
398
+ values.push({
399
+ valueIndex: value.valueIndex,
400
+ spans: value.spans,
401
+ ...(value.fragments ? { fragments: value.fragments } : null),
402
+ });
403
+ }
404
+ }
405
+ }
406
+ }
407
+ }
408
+ }
409
+ }
410
+ async #acquireReader(ownerEpoch, publicationGeneration) {
411
+ const slot = await this.#readerFor(ownerEpoch, publicationGeneration, true);
412
+ let released = false;
413
+ return {
414
+ reader: slot.reader,
415
+ definition: slot.definition,
416
+ release: () => {
417
+ if (released)
418
+ return Promise.resolve();
419
+ released = true;
420
+ slot.active--;
421
+ if (slot.active === 0) {
422
+ for (const resolve of slot.idleWaiters?.splice(0) ?? [])
423
+ resolve();
424
+ if (slot.retired) {
425
+ try {
426
+ void this.#closeReaderSlot(slot).catch((error) => this.#warnReaderClose(error));
427
+ }
428
+ catch { }
429
+ }
430
+ }
431
+ return Promise.resolve();
432
+ },
433
+ };
434
+ }
435
+ #readerFor(ownerEpoch, publicationGeneration, reserve = false) {
436
+ if (this.#closed)
437
+ return Promise.reject(new hdbError_ts_1.ServerError('Full-text index is closed', 503));
438
+ let ownReadiness;
439
+ let hasForeignPause = false;
440
+ for (const [readinessId, pausedEpoch] of this.#pauses) {
441
+ const readiness = (0, derivedIndexRuntime_ts_1.readDerivedIndexReadiness)(this.#options.auditStore, readinessId);
442
+ const completed = readiness.state === 'ready' && readiness.ownerEpoch >= pausedEpoch;
443
+ const successorCompleted = readinessId !== this.#options.readinessId &&
444
+ this.#foreignPausesObservedBeforeReady.get(readinessId) === pausedEpoch &&
445
+ (ownReadiness ??= (0, derivedIndexRuntime_ts_1.readDerivedIndexReadiness)(this.#options.auditStore, this.#options.readinessId)).state ===
446
+ 'ready';
447
+ if (completed || successorCompleted) {
448
+ resumeNativeFullTextQueryReaders(this.#nativeOptions.path, readinessId, pausedEpoch);
449
+ }
450
+ else if (readinessId !== this.#options.readinessId)
451
+ hasForeignPause = true;
452
+ }
453
+ if (hasForeignPause) {
454
+ const { auditStore, indexId, readinessId } = this.#options;
455
+ const lockKey = `derived-index:${indexId}:runner`;
456
+ if (auditStore.tryLock(lockKey)) {
457
+ try {
458
+ // Every generation holds this lock through reset and shutdown, so acquisition proves reset quiescence.
459
+ if ((0, derivedIndexRuntime_ts_1.readDerivedIndexReadiness)(auditStore, readinessId).state === 'ready')
460
+ for (const [pausedId, pausedEpoch] of [...this.#pauses])
461
+ if (pausedId !== readinessId)
462
+ resumeNativeFullTextQueryReaders(this.#nativeOptions.path, pausedId, pausedEpoch);
463
+ }
464
+ finally {
465
+ auditStore.unlock(lockKey);
466
+ }
467
+ }
468
+ }
469
+ const blocked = this.#pauses.entries().next();
470
+ if (!blocked.done) {
471
+ const [readinessId, ownerEpoch] = blocked.value;
472
+ return Promise.reject(new hdbError_ts_1.IndexRebuildingError(`Full-text index '${this.#definition.name}' is waiting for reader fence '${readinessId}' at owner epoch ${ownerEpoch}`));
473
+ }
474
+ const current = this.#readerSlot;
475
+ if (!this.#readerOperation &&
476
+ current &&
477
+ !current.retired &&
478
+ current.ownerEpoch === ownerEpoch &&
479
+ current.publicationGeneration >= publicationGeneration &&
480
+ current.configurationRevision === this.#configurationRevision) {
481
+ if (reserve)
482
+ current.active++;
483
+ return Promise.resolve(current);
484
+ }
485
+ if (this.#readerOperation)
486
+ return this.#readerOperation.then(() => this.#readerFor(ownerEpoch, publicationGeneration, reserve));
487
+ const configurationRevision = this.#configurationRevision;
488
+ this.#readerOperation = (async () => {
489
+ const existing = this.#readerSlot;
490
+ const existingMatchesIdentity = existing?.ownerEpoch === ownerEpoch && existing.configurationRevision === configurationRevision;
491
+ // Installing this operation synchronously prevents leases after observing a newer publication.
492
+ const canReload = existing?.active === 0 && existingMatchesIdentity;
493
+ try {
494
+ let reader;
495
+ let publication;
496
+ if (canReload) {
497
+ const reloadedPublicationGeneration = this.#publicationRevision();
498
+ await existing.reader.reload();
499
+ existing.publication = this.#decodeReaderPublication(existing.reader);
500
+ existing.reloadFailures = 0;
501
+ existing.publicationGeneration = reloadedPublicationGeneration;
502
+ return existing;
503
+ }
504
+ else {
505
+ const binding = await this.#getBinding();
506
+ reader = await binding.openNativeFullTextReader(this.#nativeOptions);
507
+ try {
508
+ publication = this.#decodeReaderPublication(reader);
509
+ }
510
+ catch (error) {
511
+ await reader.close().catch((closeError) => this.#warnReaderClose(closeError));
512
+ throw error;
513
+ }
514
+ if (existing)
515
+ this.#retireReaderSlot(existing);
516
+ }
517
+ const slot = {
518
+ reader,
519
+ definition: this.#definition,
520
+ ownerEpoch,
521
+ publicationGeneration,
522
+ publication,
523
+ configurationRevision,
524
+ active: 0,
525
+ retired: false,
526
+ reloadFailures: 0,
527
+ };
528
+ this.#readerSlot = slot;
529
+ return slot;
530
+ }
531
+ catch (error) {
532
+ if (canReload && error instanceof FullTextReaderPublicationError) {
533
+ this.#retireReaderSlot(existing);
534
+ }
535
+ else if (canReload && ++existing.reloadFailures >= MAX_RELOAD_FAILURES_BEFORE_REOPEN) {
536
+ this.#retireReaderSlot(existing);
537
+ }
538
+ else if (!canReload && existing && existing.active === 0 && !existingMatchesIdentity) {
539
+ this.#readerSlot = undefined;
540
+ this.#retireReaderSlot(existing);
541
+ }
542
+ throw error;
543
+ }
544
+ finally {
545
+ this.#readerOperation = undefined;
546
+ }
547
+ })();
548
+ return this.#readerOperation.then(() => this.#readerFor(ownerEpoch, publicationGeneration, reserve));
549
+ }
550
+ #decodeReaderPublication(reader) {
551
+ try {
552
+ if (reader.committedPayload === undefined)
553
+ throw new Error('missing publication');
554
+ const publication = (0, fullTextDerivedIndex_ts_1.decodeFullTextPublication)(reader.committedPayload);
555
+ if (!publication.cursor)
556
+ throw new Error('missing durable cursor');
557
+ this.#publicationRebuildRequested = false;
558
+ return publication;
559
+ }
560
+ catch (cause) {
561
+ this.#requestRebuild();
562
+ throw new FullTextReaderPublicationError(`Full-text index '${this.#definition.name}' has no valid search checkpoint`, { cause });
563
+ }
564
+ }
565
+ #refreshReader(openCold) {
566
+ try {
567
+ if (this.#closed || (!openCold && !this.#readerSlot && !this.#readerOperation))
568
+ return;
569
+ const readiness = (0, derivedIndexRuntime_ts_1.readDerivedIndexReadiness)(this.#options.auditStore, this.#options.readinessId);
570
+ if (readiness.state !== 'ready')
571
+ return;
572
+ void this.#readerFor(readiness.ownerEpoch, this.#publicationRevision()).catch((error) => {
573
+ if (nativeErrorNeedsRebuild(error))
574
+ this.#requestRebuild();
575
+ });
576
+ this.#refreshFailureWarned = false;
577
+ }
578
+ catch (error) {
579
+ if (this.#refreshFailureWarned)
580
+ return;
581
+ this.#refreshFailureWarned = true;
582
+ try {
583
+ logger.warn?.('Could not refresh a full-text reader after native publication', error);
584
+ }
585
+ catch { }
586
+ }
587
+ }
588
+ #publicationRevision() {
589
+ if (this.#closed)
590
+ throw new hdbError_ts_1.ServerError('Full-text index is closed', 503);
591
+ if (!this.#publicationSubscription)
592
+ this.#publicationSubscription = (0, derivedIndexRuntime_ts_1.subscribeDerivedIndexPublications)(this.#options.auditStore, this.#options.readinessId, () => this.#refreshReader(false));
593
+ return this.#publicationSubscription.revision();
594
+ }
595
+ #requestRebuild() {
596
+ const host = this.#derivedHost;
597
+ if (!host || this.#publicationRebuildRequested)
598
+ return;
599
+ try {
600
+ if (host.requestRebuild())
601
+ this.#publicationRebuildRequested = true;
602
+ }
603
+ catch (error) {
604
+ try {
605
+ logger.warn?.(`Could not request a rebuild for full-text index '${this.#definition.name}'`, error);
606
+ }
607
+ catch { }
608
+ }
609
+ }
610
+ #retireReaderSlot(slot) {
611
+ if (slot.retired)
612
+ return;
613
+ slot.retired = true;
614
+ this.#retiredReaderSlots.add(slot);
615
+ if (this.#readerSlot === slot)
616
+ this.#readerSlot = undefined;
617
+ if (slot.active === 0)
618
+ this.#closeReaderSlot(slot).catch((error) => this.#warnReaderClose(error));
619
+ }
620
+ #closeReaderSlot(slot) {
621
+ if (!slot.closeOperation) {
622
+ const operation = Promise.resolve()
623
+ .then(() => slot.reader.close())
624
+ .then((result) => {
625
+ this.#retiredReaderSlots.delete(slot);
626
+ if (result?.cleanupError)
627
+ this.#warnReaderClose(result.cleanupError);
628
+ });
629
+ slot.closeOperation = operation;
630
+ void operation.catch(() => {
631
+ if (slot.closeOperation === operation)
632
+ slot.closeOperation = undefined;
633
+ });
634
+ }
635
+ return slot.closeOperation;
636
+ }
637
+ async #retireAllReaders() {
638
+ await this.#readerOperation?.catch(() => undefined);
639
+ if (this.#readerSlot)
640
+ this.#retireReaderSlot(this.#readerSlot);
641
+ await Promise.all([...this.#retiredReaderSlots].map((slot) => this.#closeWhenIdle(slot)));
642
+ }
643
+ #unregister() {
644
+ const path = this.#nativeOptions.path;
645
+ const indexes = queryIndexesByPath.get(path);
646
+ indexes?.delete(this);
647
+ const sameReadinessRemains = [...(indexes ?? [])].some((index) => index.#options.readinessId === this.#options.readinessId);
648
+ if (!sameReadinessRemains)
649
+ rememberRetiredReadinessId(path, this.#options.readinessId);
650
+ if (!indexes || indexes.size === 0) {
651
+ queryIndexesByPath.delete(path);
652
+ pausedQueryPaths.delete(path);
653
+ retiredReadinessIdsByPath.delete(path);
654
+ return;
655
+ }
656
+ if (sameReadinessRemains)
657
+ return;
658
+ const ownerEpoch = pausedQueryPaths.get(path)?.get(this.#options.readinessId);
659
+ if (ownerEpoch === undefined)
660
+ return;
661
+ clearPathPause(path, this.#options.readinessId, ownerEpoch);
662
+ for (const index of indexes)
663
+ index.resume(this.#options.readinessId, ownerEpoch);
664
+ }
665
+ async #closeWhenIdle(slot) {
666
+ if (slot.active > 0)
667
+ await new Promise((resolve) => (slot.idleWaiters ??= []).push(resolve));
668
+ await this.#closeReaderSlot(slot).catch((error) => this.#warnReaderClose(error));
669
+ }
670
+ #warnReaderClose(error) {
671
+ try {
672
+ logger.warn?.('Could not close a retired full-text reader; the reader remains retired', error);
673
+ }
674
+ catch { }
675
+ }
676
+ async #getBinding() {
677
+ if (this.#binding)
678
+ return this.#binding;
679
+ const configured = this.#options.binding;
680
+ const binding = configured
681
+ ? typeof configured === 'function'
682
+ ? await configured()
683
+ : configured
684
+ : await (0, fullTextNativeBinding_ts_1.loadFullTextNativeBinding)();
685
+ const info = (0, fullTextNativeBinding_ts_1.validateFullTextQueryRuntimeInfo)(await binding.runtimeInfo());
686
+ this.#nativeOptions.limits.searchThreads = (0, fullTextNativeBinding_ts_1.nativeFullTextSearchThreads)(info, this.#nativeOptions.limits.searchThreads);
687
+ this.#maxSearchWindow = info.limits.maxSearchWindow;
688
+ this.#maxAutocompleteResults = info.limits.maxAutocompleteResults;
689
+ this.#maxSearchBudgetMilliseconds = info.limits.maxSearchBudgetMilliseconds;
690
+ this.#maxTraceRecords = info.limits.maxTraceRecords;
691
+ this.#maxTraceSourceBytes = info.limits.maxTraceSourceBytes;
692
+ return (this.#binding = binding);
693
+ }
694
+ #queryCoverage(maxLagMilliseconds) {
695
+ const coverage = this.#readCoverage(maxLagMilliseconds);
696
+ if (!coverage || coverage.state === 'unknown') {
697
+ this.#refreshReader(true);
698
+ const age = coverage?.lagUpperBoundMilliseconds;
699
+ throw new hdbError_ts_1.DerivedIndexLagError(`Cannot certify full-text index coverage within ${maxLagMilliseconds} ms` +
700
+ (age === undefined ? '; freshness is unknown' : `; last certified ${Math.ceil(age)} ms ago`) +
701
+ '; retry this query');
702
+ }
703
+ return coverage;
704
+ }
705
+ #readCoverage(maxLagMilliseconds) {
706
+ return (0, derivedIndexRuntime_ts_1.readDerivedIndexCoverage)(this.#options.auditStore, this.#options.readinessId, () => this.#readerSlot?.publication.cursor, maxLagMilliseconds);
707
+ }
708
+ }
709
+ exports.FullTextQueryIndex = FullTextQueryIndex;
710
+ async function pauseNativeFullTextQueryReaders(path, readinessId, ownerEpoch, allowUnregisteredReadiness = false) {
711
+ const indexes = queryIndexesByPath.get(path);
712
+ if (!indexes || indexes.size === 0)
713
+ return;
714
+ if (!allowUnregisteredReadiness && retiredReadinessIdsByPath.get(path)?.has(readinessId))
715
+ return;
716
+ let pauses = pausedQueryPaths.get(path);
717
+ if (!pauses)
718
+ pausedQueryPaths.set(path, (pauses = new Map()));
719
+ const current = pauses.get(readinessId);
720
+ if (current === undefined || current <= ownerEpoch)
721
+ pauses.set(readinessId, ownerEpoch);
722
+ await Promise.all([...indexes].map((index) => index.pause(readinessId, ownerEpoch)));
723
+ }
724
+ function resumeNativeFullTextQueryReaders(path, readinessId, ownerEpoch) {
725
+ clearPathPause(path, readinessId, ownerEpoch);
726
+ for (const index of queryIndexesByPath.get(path) ?? [])
727
+ index.resume(readinessId, ownerEpoch);
728
+ }
729
+ function clearPathPause(path, readinessId, ownerEpoch) {
730
+ const pauses = pausedQueryPaths.get(path);
731
+ if (pauses?.get(readinessId) !== ownerEpoch)
732
+ return;
733
+ pauses.delete(readinessId);
734
+ if (pauses.size === 0)
735
+ pausedQueryPaths.delete(path);
736
+ }
737
+ function rememberRetiredReadinessId(path, readinessId) {
738
+ let readinessIds = retiredReadinessIdsByPath.get(path);
739
+ if (!readinessIds)
740
+ retiredReadinessIdsByPath.set(path, (readinessIds = new Set()));
741
+ readinessIds.delete(readinessId);
742
+ readinessIds.add(readinessId);
743
+ if (readinessIds.size > MAX_RETIRED_READINESS_IDS_PER_PATH)
744
+ readinessIds.delete(readinessIds.values().next().value);
745
+ }
746
+ function assertFreshnessOptions(maxIndexLagMilliseconds, waitForIndexMilliseconds) {
747
+ if (typeof maxIndexLagMilliseconds !== 'number' ||
748
+ !Number.isFinite(maxIndexLagMilliseconds) ||
749
+ maxIndexLagMilliseconds < 0)
750
+ throw new hdbError_ts_1.ClientError('maxIndexLagMilliseconds must be a finite nonnegative number', 400);
751
+ if (typeof waitForIndexMilliseconds !== 'number' ||
752
+ !Number.isFinite(waitForIndexMilliseconds) ||
753
+ waitForIndexMilliseconds < 0 ||
754
+ waitForIndexMilliseconds > hnswDerivedIndex_ts_1.MAX_WAIT_FOR_INDEX_MILLISECONDS)
755
+ throw new hdbError_ts_1.ClientError(`waitForIndexMilliseconds must be a finite number between 0 and ${hnswDerivedIndex_ts_1.MAX_WAIT_FOR_INDEX_MILLISECONDS}`, 400);
756
+ }
757
+ function leafExpression(condition) {
758
+ const leaf = leafDescriptor(condition);
759
+ return { text: leaf.text, mode: leaf.mode, ...(leaf.fields ? { fields: leaf.fields } : null) };
760
+ }
761
+ function expressionUsesAutocomplete(expression) {
762
+ if ('text' in expression)
763
+ return expression.mode === 'prefix' || expression.mode === 'fuzzy-prefix';
764
+ if (expression.operator === 'not')
765
+ return expressionUsesAutocomplete(expression.clause);
766
+ return expression.clauses.some(expressionUsesAutocomplete);
767
+ }
768
+ function leafDescriptor(condition) {
769
+ const mode = (0, fullTextQueryProtocol_ts_1.fullTextComparatorMode)(condition.comparator);
770
+ if (!mode || typeof condition.value !== 'string' || condition.value.length === 0)
771
+ throw new hdbError_ts_1.ClientError('Full-text conditions require a supported comparator and non-empty string value', 400);
772
+ return { text: condition.value, mode, ...(condition.fields ? { fields: condition.fields } : null) };
773
+ }
774
+ async function sourceFields(record, definition, selected, queryDeadline) {
775
+ const fields = Object.create(null);
776
+ const deadline = Math.min(queryDeadline, performance.now() + HIGHLIGHT_BLOB_READ_TIMEOUT_MILLISECONDS);
777
+ for (const source of definition.fields) {
778
+ if (!selected.has(source.name))
779
+ continue;
780
+ const value = record[source.name];
781
+ if (typeof value === 'string')
782
+ fields[source.name] = value;
783
+ else if (Array.isArray(value))
784
+ fields[source.name] = value.filter((entry) => typeof entry === 'string');
785
+ else if (source.mediaType === 'text/plain' && value instanceof Blob) {
786
+ const remaining = deadline - performance.now();
787
+ if (remaining <= 0)
788
+ throw new hdbError_ts_1.DerivedIndexLagError('Full-text highlight source read timed out; retry the query');
789
+ let bytes;
790
+ try {
791
+ bytes = await withTimeout(value.arrayBuffer(), remaining);
792
+ }
793
+ catch {
794
+ throw new hdbError_ts_1.DerivedIndexLagError('Full-text highlight source is temporarily unavailable; retry the query');
795
+ }
796
+ fields[source.name] = UTF8_DECODER.decode(bytes);
797
+ }
798
+ }
799
+ return fields;
800
+ }
801
+ function traceSourceBytes(fields) {
802
+ let bytes = 0;
803
+ for (const value of Object.values(fields)) {
804
+ if (typeof value === 'string')
805
+ bytes += Buffer.byteLength(value);
806
+ else
807
+ for (const item of value)
808
+ bytes += Buffer.byteLength(item);
809
+ }
810
+ return bytes;
811
+ }
812
+ function traceEntryBytes(record, definition, selected) {
813
+ let bytes = 0;
814
+ for (const source of definition.fields) {
815
+ if (!selected.has(source.name))
816
+ continue;
817
+ const value = record[source.name];
818
+ if (typeof value === 'string')
819
+ bytes += Buffer.byteLength(value);
820
+ else if (Array.isArray(value)) {
821
+ for (const item of value)
822
+ if (typeof item === 'string')
823
+ bytes += Buffer.byteLength(item);
824
+ }
825
+ else if (source.mediaType === 'text/plain' && value instanceof Blob)
826
+ bytes += value.size;
827
+ }
828
+ return bytes;
829
+ }
830
+ function traceEntryBatches(entries, definition, selected, maxRecords, maxBytes) {
831
+ const batches = [];
832
+ let batch = [];
833
+ let batchBytes = 0;
834
+ for (const entry of entries) {
835
+ const bytes = traceEntryBytes(entry.record, definition, selected);
836
+ if (bytes > maxBytes)
837
+ throw new hdbError_ts_1.ClientError(`Full-text highlight source exceeds the ${maxBytes}-byte native trace limit`, 400);
838
+ if (batch.length > 0 && (batch.length >= maxRecords || batchBytes + bytes > maxBytes)) {
839
+ batches.push(batch);
840
+ batch = [];
841
+ batchBytes = 0;
842
+ }
843
+ batch.push(entry);
844
+ batchBytes += bytes;
845
+ }
846
+ if (batch.length > 0)
847
+ batches.push(batch);
848
+ return batches;
849
+ }
850
+ function traceSourceBatches(records, maxBytes) {
851
+ const batches = [];
852
+ let batch = [];
853
+ let batchBytes = 0;
854
+ for (const record of records) {
855
+ const bytes = traceSourceBytes(record.fields);
856
+ if (bytes > maxBytes)
857
+ throw new hdbError_ts_1.ClientError(`Full-text highlight source exceeds the ${maxBytes}-byte native trace limit`, 400);
858
+ if (batch.length > 0 && batchBytes + bytes > maxBytes) {
859
+ batches.push(batch);
860
+ batch = [];
861
+ batchBytes = 0;
862
+ }
863
+ batch.push(record);
864
+ batchBytes += bytes;
865
+ }
866
+ if (batch.length > 0)
867
+ batches.push(batch);
868
+ return batches;
869
+ }
870
+ function decodeNativeId(id, tableId) {
871
+ const prefix = `${tableId}.`;
872
+ if (!id.startsWith(prefix))
873
+ throw new hdbError_ts_1.ServerError('Full-text index returned an invalid record identity', 500);
874
+ try {
875
+ return (0, ordered_binary_1.fromBufferKey)(Buffer.from(id.slice(prefix.length), 'base64url'));
876
+ }
877
+ catch {
878
+ throw new hdbError_ts_1.ServerError('Full-text index returned an invalid record identity', 500);
879
+ }
880
+ }
881
+ function assertReady(readiness, name) {
882
+ if (readiness.state === 'ready')
883
+ return;
884
+ if (readiness.state === 'unavailable')
885
+ throw new hdbError_ts_1.ServerError(`Full-text index '${name}' is unavailable`, 503);
886
+ throw new hdbError_ts_1.IndexRebuildingError(`Full-text index '${name}' is not ready`);
887
+ }
888
+ function publicSearchError(error, name) {
889
+ if (error instanceof FullTextReaderPublicationError)
890
+ return new hdbError_ts_1.IndexRebuildingError(`Full-text index '${name}' is not ready`);
891
+ if (error instanceof hdbError_ts_1.ClientError || error instanceof hdbError_ts_1.ServerError)
892
+ return error;
893
+ const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
894
+ if (code === 'E_RELOAD_FAILED')
895
+ return new hdbError_ts_1.DerivedIndexLagError(`Full-text index '${name}' could not refresh its search snapshot; retry this query`);
896
+ if (typeof code === 'string' && REBUILD_REQUIRED_CODES.has(code))
897
+ return new hdbError_ts_1.IndexRebuildingError(`Full-text index '${name}' is not ready`);
898
+ if (code === 'E_QUEUE_FULL' || code === 'E_TIMEOUT' || code === 'E_RESOURCE_LIMIT')
899
+ return new hdbError_ts_1.ServerError(`Full-text index '${name}' is busy`, 503);
900
+ if (code === 'E_INVALID_ARGUMENT' || code === 'E_PREFIX_TOO_BROAD')
901
+ return new hdbError_ts_1.ClientError(`Full-text query on '${name}' is invalid`, 400);
902
+ if (code === 'E_RESULT_TOO_LARGE')
903
+ return new hdbError_ts_1.ClientError(`Full-text query on '${name}' is too large`, 413);
904
+ return new hdbError_ts_1.ServerError(`Full-text search on '${name}' failed`, 500);
905
+ }
906
+ function nativeErrorNeedsRebuild(error) {
907
+ const code = error && typeof error === 'object' && 'code' in error ? error.code : undefined;
908
+ return typeof code === 'string' && REBUILD_REQUIRED_CODES.has(code);
909
+ }
910
+ const REBUILD_REQUIRED_CODES = new Set([
911
+ 'E_INDEX_NOT_READY',
912
+ 'E_INDEX_CORRUPT',
913
+ 'E_IDENTITY_MISMATCH',
914
+ 'E_INCOMPLETE_CREATE',
915
+ 'E_SCHEMA_MISMATCH',
916
+ 'E_INDEX_FORMAT_INCOMPATIBLE',
917
+ ]);
918
+ function remainingSearchBudget(deadline) {
919
+ const remaining = Math.floor(deadline - performance.now());
920
+ if (remaining <= 0)
921
+ throw new hdbError_ts_1.ServerError('Full-text search exceeded its execution budget', 503);
922
+ return remaining;
923
+ }
924
+ function digestGeneration(value) {
925
+ return (0, node_crypto_1.createHash)('sha256').update(value).digest('hex');
926
+ }
927
+ function queryDefinitionSnapshot(definition) {
928
+ return JSON.stringify({
929
+ fields: definition.fields.map(({ name, weight, highlight }) => ({ name, weight, highlight })),
930
+ highlighting: definition.highlighting,
931
+ });
932
+ }
933
+ function withTimeout(promise, milliseconds, timeoutError = () => new Error('Full-text highlight source read timed out')) {
934
+ let timer;
935
+ return Promise.race([
936
+ promise,
937
+ new Promise((_resolve, reject) => {
938
+ timer = setTimeout(() => reject(timeoutError()), milliseconds);
939
+ timer.unref?.();
940
+ }),
941
+ ]).finally(() => clearTimeout(timer));
942
+ }
943
+ //# sourceMappingURL=fullTextQueryIndex.js.map