@thomasfosterau/effect-rdf 0.0.0 → 0.1.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 (776) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +2250 -1
  3. package/dist/Algebra-CGG4oae3.mjs +433 -0
  4. package/dist/Algebra-CGG4oae3.mjs.map +1 -0
  5. package/dist/Algebra-uGsIEOUA.d.mts +446 -0
  6. package/dist/Ast-CPRZmBvk.mjs +552 -0
  7. package/dist/Ast-CPRZmBvk.mjs.map +1 -0
  8. package/dist/Ast-vcw2W-lf.d.mts +827 -0
  9. package/dist/Bindings-Ck3m7JRC.mjs +249 -0
  10. package/dist/Bindings-Ck3m7JRC.mjs.map +1 -0
  11. package/dist/Bindings-DiKpBd7f.d.mts +153 -0
  12. package/dist/ClientErrors-CpXdFX5u.mjs +128 -0
  13. package/dist/ClientErrors-CpXdFX5u.mjs.map +1 -0
  14. package/dist/ClientErrors-D4IZHUM-.d.mts +101 -0
  15. package/dist/ClientFormats-CXomkXLV.mjs +73 -0
  16. package/dist/ClientFormats-CXomkXLV.mjs.map +1 -0
  17. package/dist/ClientFormats-Dm57ZPwR.d.mts +36 -0
  18. package/dist/Csv2Json-DynEcwCh.mjs +194 -0
  19. package/dist/Csv2Json-DynEcwCh.mjs.map +1 -0
  20. package/dist/Csv2Json-aXNVDoXQ.d.mts +40 -0
  21. package/dist/Csv2Rdf-8maXP6mt.d.mts +41 -0
  22. package/dist/Csv2Rdf-DuSEkaKE.mjs +161 -0
  23. package/dist/Csv2Rdf-DuSEkaKE.mjs.map +1 -0
  24. package/dist/Dataset-BlmlcI7J.mjs +782 -0
  25. package/dist/Dataset-BlmlcI7J.mjs.map +1 -0
  26. package/dist/Dataset-DS3ESOcO.d.mts +426 -0
  27. package/dist/Dataset.d.mts +2 -0
  28. package/dist/Dataset.mjs +1 -0
  29. package/dist/Datatype-CxMpamHC.d.mts +212 -0
  30. package/dist/Datatype-DQvkNkiH.mjs +1001 -0
  31. package/dist/Datatype-DQvkNkiH.mjs.map +1 -0
  32. package/dist/Dialect-8ChFj5EX.d.mts +113 -0
  33. package/dist/Dialect-CzVH38uo.mjs +165 -0
  34. package/dist/Dialect-CzVH38uo.mjs.map +1 -0
  35. package/dist/DocumentLoader-D3lZREnB.mjs +346 -0
  36. package/dist/DocumentLoader-D3lZREnB.mjs.map +1 -0
  37. package/dist/DocumentLoader-ZUCEVrW5.d.mts +178 -0
  38. package/dist/DublinCore-AnwqxRx6.mjs +137 -0
  39. package/dist/DublinCore-AnwqxRx6.mjs.map +1 -0
  40. package/dist/DublinCore-Dq-tVA5d.d.mts +119 -0
  41. package/dist/Engine-CYPB3g4h.d.mts +144 -0
  42. package/dist/Engine-DF8PN7g-.mjs +872 -0
  43. package/dist/Engine-DF8PN7g-.mjs.map +1 -0
  44. package/dist/Errors-CMdV1RhU.mjs +37 -0
  45. package/dist/Errors-CMdV1RhU.mjs.map +1 -0
  46. package/dist/Errors-u2bDjUeM.d.mts +30 -0
  47. package/dist/Evaluator-DEsU4d1o.d.mts +50 -0
  48. package/dist/Evaluator-DOY2-guC.mjs +281 -0
  49. package/dist/Evaluator-DOY2-guC.mjs.map +1 -0
  50. package/dist/Exif-CpqniYQd.d.mts +78 -0
  51. package/dist/Exif-DjkCfEB-.mjs +89 -0
  52. package/dist/Exif-DjkCfEB-.mjs.map +1 -0
  53. package/dist/Expression-BIMMvduQ.mjs +230 -0
  54. package/dist/Expression-BIMMvduQ.mjs.map +1 -0
  55. package/dist/Expression-W8A9cyX7.d.mts +89 -0
  56. package/dist/Extract-Bop85jES.mjs +220 -0
  57. package/dist/Extract-Bop85jES.mjs.map +1 -0
  58. package/dist/Extract-C_pCvuTC.d.mts +88 -0
  59. package/dist/Federation-BcNrozc1.d.mts +52 -0
  60. package/dist/Federation-CHScBkaK.mjs +130 -0
  61. package/dist/Federation-CHScBkaK.mjs.map +1 -0
  62. package/dist/Functions-AvjNcId_.mjs +1346 -0
  63. package/dist/Functions-AvjNcId_.mjs.map +1 -0
  64. package/dist/Functions-OQJZP-F6.d.mts +111 -0
  65. package/dist/Generator-C52mmq01.d.mts +50 -0
  66. package/dist/Generator-D3utCJC7.mjs +205 -0
  67. package/dist/Generator-D3utCJC7.mjs.map +1 -0
  68. package/dist/Grammar-CPlSxGH6.mjs +200 -0
  69. package/dist/Grammar-CPlSxGH6.mjs.map +1 -0
  70. package/dist/Grammar-CRhnRoCu.d.mts +148 -0
  71. package/dist/Grammar-D6jZdJQ3.d.mts +169 -0
  72. package/dist/Grammar-mQ8CgE1M.mjs +258 -0
  73. package/dist/Grammar-mQ8CgE1M.mjs.map +1 -0
  74. package/dist/GraphStore-DhUa4nFO.d.mts +45 -0
  75. package/dist/GraphStore-DvbqwKy1.mjs +212 -0
  76. package/dist/GraphStore-DvbqwKy1.mjs.map +1 -0
  77. package/dist/Iri-BB8Ks-BF.d.mts +84 -0
  78. package/dist/Iri-Cr92gsQV.mjs +232 -0
  79. package/dist/Iri-Cr92gsQV.mjs.map +1 -0
  80. package/dist/Iri.d.mts +2 -0
  81. package/dist/Iri.mjs +1 -0
  82. package/dist/Isomorphism-B6qTY-xy.d.mts +28 -0
  83. package/dist/Isomorphism-BmqxhKyJ.mjs +232 -0
  84. package/dist/Isomorphism-BmqxhKyJ.mjs.map +1 -0
  85. package/dist/Isomorphism-DInKnWIy.mjs +390 -0
  86. package/dist/Isomorphism-DInKnWIy.mjs.map +1 -0
  87. package/dist/Isomorphism-DvSfZXLR.d.mts +37 -0
  88. package/dist/Isomorphism.d.mts +2 -0
  89. package/dist/Isomorphism.mjs +1 -0
  90. package/dist/JsonLd-DOwS2FHg.mjs +2836 -0
  91. package/dist/JsonLd-DOwS2FHg.mjs.map +1 -0
  92. package/dist/JsonLd-DobFrQNa.d.mts +242 -0
  93. package/dist/JsonLdError-C9J-BxfG.mjs +106 -0
  94. package/dist/JsonLdError-C9J-BxfG.mjs.map +1 -0
  95. package/dist/JsonLdError-DSOfHkOy.d.mts +43 -0
  96. package/dist/LanguageTag-BCu8rcmX.d.mts +38 -0
  97. package/dist/LanguageTag-BcOpMGZ4.mjs +89 -0
  98. package/dist/LanguageTag-BcOpMGZ4.mjs.map +1 -0
  99. package/dist/LanguageTag.d.mts +2 -0
  100. package/dist/LanguageTag.mjs +1 -0
  101. package/dist/Lexical-Cg0JHrf6.mjs +243 -0
  102. package/dist/Lexical-Cg0JHrf6.mjs.map +1 -0
  103. package/dist/Lexical-D3zySYVS.d.mts +163 -0
  104. package/dist/Manifest-B6xf6mUc.mjs +148 -0
  105. package/dist/Manifest-B6xf6mUc.mjs.map +1 -0
  106. package/dist/Manifest-DQUMRBFr.d.mts +98 -0
  107. package/dist/Mapping-BgG74x3U.d.mts +63 -0
  108. package/dist/Mapping-Dc1ZGirk.mjs +259 -0
  109. package/dist/Mapping-Dc1ZGirk.mjs.map +1 -0
  110. package/dist/Mcp-1DwTTKOK.mjs +48 -0
  111. package/dist/Mcp-1DwTTKOK.mjs.map +1 -0
  112. package/dist/Mcp-d-pX9erx.d.mts +25 -0
  113. package/dist/Message-CK_DGQuu.mjs +95 -0
  114. package/dist/Message-CK_DGQuu.mjs.map +1 -0
  115. package/dist/Message-fIvTJSXM.d.mts +49 -0
  116. package/dist/Metadata-BbffwGDZ.mjs +445 -0
  117. package/dist/Metadata-BbffwGDZ.mjs.map +1 -0
  118. package/dist/Metadata-CEt3yc1-.d.mts +901 -0
  119. package/dist/Metadata-D4HsQNXr.mjs +1273 -0
  120. package/dist/Metadata-D4HsQNXr.mjs.map +1 -0
  121. package/dist/Metadata-nzS7QKRj.d.mts +350 -0
  122. package/dist/Model-DaMmxurZ.d.mts +293 -0
  123. package/dist/Model-DlPzRYhF.mjs +528 -0
  124. package/dist/Model-DlPzRYhF.mjs.map +1 -0
  125. package/dist/N3-BzyV-KIH.mjs +974 -0
  126. package/dist/N3-BzyV-KIH.mjs.map +1 -0
  127. package/dist/N3-DSLnonDn.d.mts +100 -0
  128. package/dist/NQuads-C1VBOJ3-.mjs +117 -0
  129. package/dist/NQuads-C1VBOJ3-.mjs.map +1 -0
  130. package/dist/NQuads-FjFZikFg.d.mts +76 -0
  131. package/dist/NTriples-D-kLSEAf.mjs +120 -0
  132. package/dist/NTriples-D-kLSEAf.mjs.map +1 -0
  133. package/dist/NTriples-D34OspfW.d.mts +76 -0
  134. package/dist/Namespace-ClTUO_ya.d.mts +42 -0
  135. package/dist/Namespace-DHFIsORd.mjs +75 -0
  136. package/dist/Namespace-DHFIsORd.mjs.map +1 -0
  137. package/dist/Namespace.d.mts +2 -0
  138. package/dist/Namespace.mjs +1 -0
  139. package/dist/Namespaces-Bz85vpjW.mjs +235 -0
  140. package/dist/Namespaces-Bz85vpjW.mjs.map +1 -0
  141. package/dist/Namespaces-C1jW6EDo.d.mts +178 -0
  142. package/dist/Optimizer-BWWQRQPY.mjs +168 -0
  143. package/dist/Optimizer-BWWQRQPY.mjs.map +1 -0
  144. package/dist/Optimizer-DUpUow6k.d.mts +26 -0
  145. package/dist/Options-BLBGL4HE.mjs +72 -0
  146. package/dist/Options-BLBGL4HE.mjs.map +1 -0
  147. package/dist/Options-BommQwP9.d.mts +127 -0
  148. package/dist/Packet-CA76wVX3.mjs +197 -0
  149. package/dist/Packet-CA76wVX3.mjs.map +1 -0
  150. package/dist/Packet-Cy5g6XuW.d.mts +130 -0
  151. package/dist/Parser-p1Gyr0QN.d.mts +85 -0
  152. package/dist/Parser-xARsOWXk.mjs +1317 -0
  153. package/dist/Parser-xARsOWXk.mjs.map +1 -0
  154. package/dist/Path-B20Yp8KE.mjs +284 -0
  155. package/dist/Path-B20Yp8KE.mjs.map +1 -0
  156. package/dist/Path-DRB8e-Zn.d.mts +181 -0
  157. package/dist/Pdf-B9RZn--8.d.mts +77 -0
  158. package/dist/Pdf-CKK6dkZn.mjs +89 -0
  159. package/dist/Pdf-CKK6dkZn.mjs.map +1 -0
  160. package/dist/PdfA-CUjSuntT.d.mts +109 -0
  161. package/dist/PdfA-CleOhuL6.mjs +124 -0
  162. package/dist/PdfA-CleOhuL6.mjs.map +1 -0
  163. package/dist/Photoshop-CiHo80qV.mjs +233 -0
  164. package/dist/Photoshop-CiHo80qV.mjs.map +1 -0
  165. package/dist/Photoshop-udKZ0I3N.d.mts +204 -0
  166. package/dist/PrefixMap-BHFPDLO-.mjs +103 -0
  167. package/dist/PrefixMap-BHFPDLO-.mjs.map +1 -0
  168. package/dist/PrefixMap-BMlXrWNd.d.mts +64 -0
  169. package/dist/PrefixMap.d.mts +2 -0
  170. package/dist/PrefixMap.mjs +1 -0
  171. package/dist/Processor-CMmecFsb.mjs +198 -0
  172. package/dist/Processor-CMmecFsb.mjs.map +1 -0
  173. package/dist/Processor-FJPvO0CB.d.mts +435 -0
  174. package/dist/Protocol-BA7OkNgp.mjs +202 -0
  175. package/dist/Protocol-BA7OkNgp.mjs.map +1 -0
  176. package/dist/Protocol-DlSoiIKB.d.mts +108 -0
  177. package/dist/ProtocolErrors-Ckfejnl6.d.mts +84 -0
  178. package/dist/ProtocolErrors-czDPVcX5.mjs +129 -0
  179. package/dist/ProtocolErrors-czDPVcX5.mjs.map +1 -0
  180. package/dist/Query-D9A6LOpP.mjs +364 -0
  181. package/dist/Query-D9A6LOpP.mjs.map +1 -0
  182. package/dist/Query-KqSkTYyG.d.mts +96 -0
  183. package/dist/QueryBuilder-BLK9Vfbz.mjs +674 -0
  184. package/dist/QueryBuilder-BLK9Vfbz.mjs.map +1 -0
  185. package/dist/QueryBuilder-DUqh4ECe.d.mts +529 -0
  186. package/dist/RdfJs-D6-49XB5.mjs +86 -0
  187. package/dist/RdfJs-D6-49XB5.mjs.map +1 -0
  188. package/dist/RdfJs-DXFqdWrd.d.mts +76 -0
  189. package/dist/RdfJs.d.mts +2 -0
  190. package/dist/RdfJs.mjs +1 -0
  191. package/dist/RdfJson-5aKPDlPS.d.mts +297 -0
  192. package/dist/RdfJson-BNocgW4f.mjs +548 -0
  193. package/dist/RdfJson-BNocgW4f.mjs.map +1 -0
  194. package/dist/RdfXml-DJ9G4gOq.mjs +1014 -0
  195. package/dist/RdfXml-DJ9G4gOq.mjs.map +1 -0
  196. package/dist/RdfXml-_N7yxWEp.d.mts +149 -0
  197. package/dist/Rdfs-BRVPsAjc.d.mts +84 -0
  198. package/dist/Rdfs-CyY2wVHI.mjs +167 -0
  199. package/dist/Rdfs-CyY2wVHI.mjs.map +1 -0
  200. package/dist/Rdfs.d.mts +2 -0
  201. package/dist/Rdfs.mjs +1 -0
  202. package/dist/Reasoner-BxYhx9s7.d.mts +94 -0
  203. package/dist/Reasoner-Cw90zrjv.mjs +798 -0
  204. package/dist/Reasoner-Cw90zrjv.mjs.map +1 -0
  205. package/dist/Reification-BmN4EfnM.d.mts +40 -0
  206. package/dist/Reification-dpqQvjDE.mjs +82 -0
  207. package/dist/Reification-dpqQvjDE.mjs.map +1 -0
  208. package/dist/Reification.d.mts +2 -0
  209. package/dist/Reification.mjs +1 -0
  210. package/dist/Report-XHs8htzK.mjs +121 -0
  211. package/dist/Report-XHs8htzK.mjs.map +1 -0
  212. package/dist/Report-hcXsc_19.d.mts +115 -0
  213. package/dist/Resource-B1cI8FyJ.d.mts +218 -0
  214. package/dist/Resource-sIEeNh15.mjs +374 -0
  215. package/dist/Resource-sIEeNh15.mjs.map +1 -0
  216. package/dist/Resource.d.mts +2 -0
  217. package/dist/Resource.mjs +1 -0
  218. package/dist/Results-BVNEC-Wt.d.mts +277 -0
  219. package/dist/Results-peJjGA2V.mjs +621 -0
  220. package/dist/Results-peJjGA2V.mjs.map +1 -0
  221. package/dist/ResultsStream-BhF0OcNn.mjs +639 -0
  222. package/dist/ResultsStream-BhF0OcNn.mjs.map +1 -0
  223. package/dist/ResultsStream-toYMXrOe.d.mts +100 -0
  224. package/dist/SemAct-CDchtk49.d.mts +96 -0
  225. package/dist/SemAct-CmyT4yI8.mjs +118 -0
  226. package/dist/SemAct-CmyT4yI8.mjs.map +1 -0
  227. package/dist/Serialization-DP9H5bYQ.mjs +514 -0
  228. package/dist/Serialization-DP9H5bYQ.mjs.map +1 -0
  229. package/dist/Serialization-Df8iVauT.d.mts +392 -0
  230. package/dist/Serialization.d.mts +2 -0
  231. package/dist/Serialization.mjs +1 -0
  232. package/dist/ServerFormats-CrRnjjf6.mjs +64 -0
  233. package/dist/ServerFormats-CrRnjjf6.mjs.map +1 -0
  234. package/dist/ServerFormats-DjC9NsO_.d.mts +36 -0
  235. package/dist/ServiceDescription-BERsvg-k.d.mts +54 -0
  236. package/dist/ServiceDescription-Dq5hxeGy.mjs +97 -0
  237. package/dist/ServiceDescription-Dq5hxeGy.mjs.map +1 -0
  238. package/dist/ShExC-Ctf-06CL.d.mts +67 -0
  239. package/dist/ShExC-DJbB19i3.mjs +1181 -0
  240. package/dist/ShExC-DJbB19i3.mjs.map +1 -0
  241. package/dist/ShExError-BeYFD9rv.d.mts +61 -0
  242. package/dist/ShExError-CVtq2NnM.mjs +64 -0
  243. package/dist/ShExError-CVtq2NnM.mjs.map +1 -0
  244. package/dist/ShExJ-C1u_wgyD.d.mts +531 -0
  245. package/dist/ShExJ-COiPd9Xw.mjs +532 -0
  246. package/dist/ShExJ-COiPd9Xw.mjs.map +1 -0
  247. package/dist/ShExR-ByR4mCh-.mjs +480 -0
  248. package/dist/ShExR-ByR4mCh-.mjs.map +1 -0
  249. package/dist/ShExR-CqONNNBz.d.mts +40 -0
  250. package/dist/ShapeMap-C422pxKl.d.mts +140 -0
  251. package/dist/ShapeMap-CsgKxB2G.mjs +181 -0
  252. package/dist/ShapeMap-CsgKxB2G.mjs.map +1 -0
  253. package/dist/Shapes-18GjfyBV.mjs +597 -0
  254. package/dist/Shapes-18GjfyBV.mjs.map +1 -0
  255. package/dist/Shapes-BQFDFc4Q.d.mts +306 -0
  256. package/dist/Sparql-BiYFMSpl.mjs +29 -0
  257. package/dist/Sparql-BiYFMSpl.mjs.map +1 -0
  258. package/dist/Sparql-DecpWTPh.d.mts +97 -0
  259. package/dist/SparqlClient-C_CjXbwj.mjs +333 -0
  260. package/dist/SparqlClient-C_CjXbwj.mjs.map +1 -0
  261. package/dist/SparqlClient-UPc88SHy.d.mts +290 -0
  262. package/dist/SparqlServer-CbUW-pVj.d.mts +71 -0
  263. package/dist/SparqlServer-Db7w7Cll.mjs +308 -0
  264. package/dist/SparqlServer-Db7w7Cll.mjs.map +1 -0
  265. package/dist/SqlStore-BBqFx-Wl.mjs +684 -0
  266. package/dist/SqlStore-BBqFx-Wl.mjs.map +1 -0
  267. package/dist/SqlStore-CCJo5I-e.d.mts +117 -0
  268. package/dist/Store-D0jmVfb3.d.mts +166 -0
  269. package/dist/Store-DH3Ow1GO.mjs +162 -0
  270. package/dist/Store-DH3Ow1GO.mjs.map +1 -0
  271. package/dist/Structure-BjMo4Bkc.mjs +334 -0
  272. package/dist/Structure-BjMo4Bkc.mjs.map +1 -0
  273. package/dist/Structure-n4CmDiab.d.mts +63 -0
  274. package/dist/Table-BGgm9nbM.mjs +538 -0
  275. package/dist/Table-BGgm9nbM.mjs.map +1 -0
  276. package/dist/Table-C3reiVrb.d.mts +261 -0
  277. package/dist/Term-B_4ezyXq.d.mts +619 -0
  278. package/dist/Term-CFLG1qu4.mjs +991 -0
  279. package/dist/Term-CFLG1qu4.mjs.map +1 -0
  280. package/dist/Term.d.mts +2 -0
  281. package/dist/Term.mjs +1 -0
  282. package/dist/TermCodec-CDZiEztW.mjs +397 -0
  283. package/dist/TermCodec-CDZiEztW.mjs.map +1 -0
  284. package/dist/TermCodec-_03bDXr0.d.mts +209 -0
  285. package/dist/TermCodec.d.mts +2 -0
  286. package/dist/TermCodec.mjs +1 -0
  287. package/dist/TermJson-BOPe0yve.d.mts +232 -0
  288. package/dist/TermJson-FAg3lvjl.mjs +142 -0
  289. package/dist/TermJson-FAg3lvjl.mjs.map +1 -0
  290. package/dist/TermJson.d.mts +2 -0
  291. package/dist/TermJson.mjs +1 -0
  292. package/dist/TermSchema-Bn9CoaYA.mjs +30 -0
  293. package/dist/TermSchema-Bn9CoaYA.mjs.map +1 -0
  294. package/dist/TermSchema-DBO6MroX.d.mts +6 -0
  295. package/dist/Testing-B-aPCpmu.mjs +63 -0
  296. package/dist/Testing-B-aPCpmu.mjs.map +1 -0
  297. package/dist/Testing-CF6s8P3O.d.mts +53 -0
  298. package/dist/Tiff-CR-2QeSI.d.mts +148 -0
  299. package/dist/Tiff-DlsOlZPM.mjs +169 -0
  300. package/dist/Tiff-DlsOlZPM.mjs.map +1 -0
  301. package/dist/Tools-7MdRKccr.d.mts +583 -0
  302. package/dist/Tools-ryxphZbI.mjs +329 -0
  303. package/dist/Tools-ryxphZbI.mjs.map +1 -0
  304. package/dist/Translate-B0YKKANS.d.mts +37 -0
  305. package/dist/Translate-gzWPq0Ia.mjs +308 -0
  306. package/dist/Translate-gzWPq0Ia.mjs.map +1 -0
  307. package/dist/Translation-DC9rLm2y.mjs +1535 -0
  308. package/dist/Translation-DC9rLm2y.mjs.map +1 -0
  309. package/dist/Translation-K4L9XBqX.d.mts +103 -0
  310. package/dist/TriG-BkqtqZ6Y.mjs +125 -0
  311. package/dist/TriG-BkqtqZ6Y.mjs.map +1 -0
  312. package/dist/TriG-xDjdDatp.d.mts +86 -0
  313. package/dist/Turtle-Bv1_bisW.d.mts +85 -0
  314. package/dist/Turtle-CZVUOtwl.mjs +133 -0
  315. package/dist/Turtle-CZVUOtwl.mjs.map +1 -0
  316. package/dist/ValidationReport-DBdJshW5.mjs +285 -0
  317. package/dist/ValidationReport-DBdJshW5.mjs.map +1 -0
  318. package/dist/ValidationReport-Dx3WxY0h.d.mts +192 -0
  319. package/dist/Validator-227ff9Rn.d.mts +179 -0
  320. package/dist/Validator-BzXMKDeJ.mjs +1162 -0
  321. package/dist/Validator-BzXMKDeJ.mjs.map +1 -0
  322. package/dist/Validator-Dl8cih5V.d.mts +207 -0
  323. package/dist/Validator-DmUfMbpL.mjs +568 -0
  324. package/dist/Validator-DmUfMbpL.mjs.map +1 -0
  325. package/dist/Vocab-DceKywpq.mjs +168 -0
  326. package/dist/Vocab-DceKywpq.mjs.map +1 -0
  327. package/dist/Vocab-Df-L-IwZ.d.mts +46 -0
  328. package/dist/Vocab-Do56UgBX.d.mts +81 -0
  329. package/dist/Vocab-TfpWG1Ne.mjs +118 -0
  330. package/dist/Vocab-TfpWG1Ne.mjs.map +1 -0
  331. package/dist/Vocab.d.mts +2 -0
  332. package/dist/Vocab.mjs +1 -0
  333. package/dist/Vocabulary-C6-GPOy4.d.mts +22 -0
  334. package/dist/Vocabulary-CnQl-_Z4.mjs +179 -0
  335. package/dist/Vocabulary-CnQl-_Z4.mjs.map +1 -0
  336. package/dist/Xml-B7iihYCS.mjs +976 -0
  337. package/dist/Xml-B7iihYCS.mjs.map +1 -0
  338. package/dist/Xml-CmfHS7SW.d.mts +267 -0
  339. package/dist/Xmp-D7CKA7MZ.d.mts +111 -0
  340. package/dist/Xmp-DCGN9pOD.mjs +307 -0
  341. package/dist/Xmp-DCGN9pOD.mjs.map +1 -0
  342. package/dist/XmpBasic-CP38jpR_.mjs +73 -0
  343. package/dist/XmpBasic-CP38jpR_.mjs.map +1 -0
  344. package/dist/XmpBasic-Cmbe53rQ.d.mts +64 -0
  345. package/dist/XmpMM-BfL_TgJF.mjs +73 -0
  346. package/dist/XmpMM-BfL_TgJF.mjs.map +1 -0
  347. package/dist/XmpMM-Dqm3IX8p.d.mts +63 -0
  348. package/dist/XmpRights-BKPtoI5L.mjs +73 -0
  349. package/dist/XmpRights-BKPtoI5L.mjs.map +1 -0
  350. package/dist/XmpRights-CaALZQz2.d.mts +63 -0
  351. package/dist/Xsd-Cdgx5zRB.mjs +405 -0
  352. package/dist/Xsd-Cdgx5zRB.mjs.map +1 -0
  353. package/dist/Xsd-D2elNhSm.d.mts +187 -0
  354. package/dist/Xsd.d.mts +2 -0
  355. package/dist/Xsd.mjs +1 -0
  356. package/dist/accessors-CEjaojuQ.mjs +28 -0
  357. package/dist/accessors-CEjaojuQ.mjs.map +1 -0
  358. package/dist/codec-Lb2T96rv.d.mts +20 -0
  359. package/dist/codec-QNo7IdJF.mjs +389 -0
  360. package/dist/codec-QNo7IdJF.mjs.map +1 -0
  361. package/dist/csvw/Csv2Json.d.mts +2 -0
  362. package/dist/csvw/Csv2Json.mjs +1 -0
  363. package/dist/csvw/Csv2Rdf.d.mts +2 -0
  364. package/dist/csvw/Csv2Rdf.mjs +1 -0
  365. package/dist/csvw/Datatype.d.mts +2 -0
  366. package/dist/csvw/Datatype.mjs +1 -0
  367. package/dist/csvw/Metadata.d.mts +2 -0
  368. package/dist/csvw/Metadata.mjs +1 -0
  369. package/dist/csvw/Processor.d.mts +2 -0
  370. package/dist/csvw/Processor.mjs +1 -0
  371. package/dist/csvw/Report.d.mts +2 -0
  372. package/dist/csvw/Report.mjs +1 -0
  373. package/dist/csvw/Table.d.mts +2 -0
  374. package/dist/csvw/Table.mjs +1 -0
  375. package/dist/csvw/index.d.mts +8 -0
  376. package/dist/csvw/index.mjs +8 -0
  377. package/dist/index-Cms2TYfC.d.mts +16 -0
  378. package/dist/index-Ct8xFmRs.d.mts +7 -0
  379. package/dist/index-D4QFwOjm.d.mts +28 -0
  380. package/dist/index.d.mts +18 -0
  381. package/dist/index.mjs +17 -0
  382. package/dist/jsonld/DocumentLoader.d.mts +2 -0
  383. package/dist/jsonld/DocumentLoader.mjs +1 -0
  384. package/dist/jsonld/JsonLd.d.mts +2 -0
  385. package/dist/jsonld/JsonLd.mjs +1 -0
  386. package/dist/jsonld/JsonLdError.d.mts +2 -0
  387. package/dist/jsonld/JsonLdError.mjs +1 -0
  388. package/dist/jsonld/index.d.mts +4 -0
  389. package/dist/jsonld/index.mjs +4 -0
  390. package/dist/lists-D-OpQ0Ir.mjs +77 -0
  391. package/dist/lists-D-OpQ0Ir.mjs.map +1 -0
  392. package/dist/loop-D5-gNx9K.mjs +21 -0
  393. package/dist/loop-D5-gNx9K.mjs.map +1 -0
  394. package/dist/loop-DZ2hXlr_.mjs +21 -0
  395. package/dist/loop-DZ2hXlr_.mjs.map +1 -0
  396. package/dist/n3/Isomorphism.d.mts +2 -0
  397. package/dist/n3/Isomorphism.mjs +1 -0
  398. package/dist/n3/Mapping.d.mts +2 -0
  399. package/dist/n3/Mapping.mjs +1 -0
  400. package/dist/n3/Model.d.mts +2 -0
  401. package/dist/n3/Model.mjs +1 -0
  402. package/dist/n3/N3.d.mts +2 -0
  403. package/dist/n3/N3.mjs +1 -0
  404. package/dist/n3/Reasoner.d.mts +2 -0
  405. package/dist/n3/Reasoner.mjs +2 -0
  406. package/dist/n3/Vocab.d.mts +2 -0
  407. package/dist/n3/Vocab.mjs +1 -0
  408. package/dist/n3/index.d.mts +7 -0
  409. package/dist/n3/index.mjs +7 -0
  410. package/dist/ntriples/Grammar.d.mts +2 -0
  411. package/dist/ntriples/Grammar.mjs +1 -0
  412. package/dist/ntriples/Lexical.d.mts +2 -0
  413. package/dist/ntriples/Lexical.mjs +1 -0
  414. package/dist/ntriples/NQuads.d.mts +2 -0
  415. package/dist/ntriples/NQuads.mjs +1 -0
  416. package/dist/ntriples/NTriples.d.mts +2 -0
  417. package/dist/ntriples/NTriples.mjs +1 -0
  418. package/dist/ntriples/index.d.mts +5 -0
  419. package/dist/ntriples/index.mjs +5 -0
  420. package/dist/rdfjson/RdfJson.d.mts +2 -0
  421. package/dist/rdfjson/RdfJson.mjs +1 -0
  422. package/dist/rdfjson/index.d.mts +2 -0
  423. package/dist/rdfjson/index.mjs +1 -0
  424. package/dist/rdfxml/RdfXml.d.mts +2 -0
  425. package/dist/rdfxml/RdfXml.mjs +1 -0
  426. package/dist/rdfxml/Xml.d.mts +2 -0
  427. package/dist/rdfxml/Xml.mjs +1 -0
  428. package/dist/rdfxml/index.d.mts +3 -0
  429. package/dist/rdfxml/index.mjs +3 -0
  430. package/dist/rolldown-runtime-D8jQpDG7.mjs +12 -0
  431. package/dist/serialize-96KBvKaf.mjs +1463 -0
  432. package/dist/serialize-96KBvKaf.mjs.map +1 -0
  433. package/dist/serialize-DsoXdM6n.d.mts +37 -0
  434. package/dist/shacl/Message.d.mts +2 -0
  435. package/dist/shacl/Message.mjs +1 -0
  436. package/dist/shacl/Path.d.mts +2 -0
  437. package/dist/shacl/Path.mjs +1 -0
  438. package/dist/shacl/Shapes.d.mts +2 -0
  439. package/dist/shacl/Shapes.mjs +1 -0
  440. package/dist/shacl/Sparql.d.mts +2 -0
  441. package/dist/shacl/Sparql.mjs +1 -0
  442. package/dist/shacl/ValidationReport.d.mts +2 -0
  443. package/dist/shacl/ValidationReport.mjs +1 -0
  444. package/dist/shacl/Validator.d.mts +2 -0
  445. package/dist/shacl/Validator.mjs +1 -0
  446. package/dist/shacl/Vocabulary.d.mts +2 -0
  447. package/dist/shacl/Vocabulary.mjs +1 -0
  448. package/dist/shacl/index.d.mts +9 -0
  449. package/dist/shacl/index.mjs +8 -0
  450. package/dist/shex/SemAct.d.mts +2 -0
  451. package/dist/shex/SemAct.mjs +1 -0
  452. package/dist/shex/ShExC.d.mts +2 -0
  453. package/dist/shex/ShExC.mjs +1 -0
  454. package/dist/shex/ShExError.d.mts +2 -0
  455. package/dist/shex/ShExError.mjs +1 -0
  456. package/dist/shex/ShExJ.d.mts +2 -0
  457. package/dist/shex/ShExJ.mjs +2 -0
  458. package/dist/shex/ShExR.d.mts +2 -0
  459. package/dist/shex/ShExR.mjs +1 -0
  460. package/dist/shex/ShapeMap.d.mts +2 -0
  461. package/dist/shex/ShapeMap.mjs +1 -0
  462. package/dist/shex/Structure.d.mts +2 -0
  463. package/dist/shex/Structure.mjs +2 -0
  464. package/dist/shex/Validator.d.mts +2 -0
  465. package/dist/shex/Validator.mjs +4 -0
  466. package/dist/shex/index.d.mts +9 -0
  467. package/dist/shex/index.mjs +9 -0
  468. package/dist/sparql/Algebra.d.mts +2 -0
  469. package/dist/sparql/Algebra.mjs +1 -0
  470. package/dist/sparql/Ast.d.mts +2 -0
  471. package/dist/sparql/Ast.mjs +1 -0
  472. package/dist/sparql/Bindings.d.mts +2 -0
  473. package/dist/sparql/Bindings.mjs +1 -0
  474. package/dist/sparql/ClientErrors.d.mts +2 -0
  475. package/dist/sparql/ClientErrors.mjs +1 -0
  476. package/dist/sparql/ClientFormats.d.mts +2 -0
  477. package/dist/sparql/ClientFormats.mjs +1 -0
  478. package/dist/sparql/Engine.d.mts +2 -0
  479. package/dist/sparql/Engine.mjs +1 -0
  480. package/dist/sparql/Errors.d.mts +2 -0
  481. package/dist/sparql/Errors.mjs +1 -0
  482. package/dist/sparql/Expression.d.mts +2 -0
  483. package/dist/sparql/Expression.mjs +1 -0
  484. package/dist/sparql/Federation.d.mts +2 -0
  485. package/dist/sparql/Federation.mjs +1 -0
  486. package/dist/sparql/Functions.d.mts +2 -0
  487. package/dist/sparql/Functions.mjs +1 -0
  488. package/dist/sparql/Generator.d.mts +2 -0
  489. package/dist/sparql/Generator.mjs +1 -0
  490. package/dist/sparql/GraphStore.d.mts +2 -0
  491. package/dist/sparql/GraphStore.mjs +1 -0
  492. package/dist/sparql/Optimizer.d.mts +2 -0
  493. package/dist/sparql/Optimizer.mjs +1 -0
  494. package/dist/sparql/Options.d.mts +2 -0
  495. package/dist/sparql/Options.mjs +1 -0
  496. package/dist/sparql/Parser.d.mts +2 -0
  497. package/dist/sparql/Parser.mjs +1 -0
  498. package/dist/sparql/Protocol.d.mts +2 -0
  499. package/dist/sparql/Protocol.mjs +1 -0
  500. package/dist/sparql/ProtocolErrors.d.mts +2 -0
  501. package/dist/sparql/ProtocolErrors.mjs +1 -0
  502. package/dist/sparql/QueryBuilder.d.mts +2 -0
  503. package/dist/sparql/QueryBuilder.mjs +1 -0
  504. package/dist/sparql/Results.d.mts +2 -0
  505. package/dist/sparql/Results.mjs +1 -0
  506. package/dist/sparql/ResultsStream.d.mts +2 -0
  507. package/dist/sparql/ResultsStream.mjs +1 -0
  508. package/dist/sparql/ServerFormats.d.mts +2 -0
  509. package/dist/sparql/ServerFormats.mjs +1 -0
  510. package/dist/sparql/ServiceDescription.d.mts +2 -0
  511. package/dist/sparql/ServiceDescription.mjs +1 -0
  512. package/dist/sparql/SparqlClient.d.mts +2 -0
  513. package/dist/sparql/SparqlClient.mjs +1 -0
  514. package/dist/sparql/SparqlServer.d.mts +2 -0
  515. package/dist/sparql/SparqlServer.mjs +1 -0
  516. package/dist/sparql/Store.d.mts +2 -0
  517. package/dist/sparql/Store.mjs +1 -0
  518. package/dist/sparql/TermSchema.d.mts +3 -0
  519. package/dist/sparql/TermSchema.mjs +2 -0
  520. package/dist/sparql/Testing.d.mts +2 -0
  521. package/dist/sparql/Testing.mjs +1 -0
  522. package/dist/sparql/Translate.d.mts +2 -0
  523. package/dist/sparql/Translate.mjs +1 -0
  524. package/dist/sparql/ai/Mcp.d.mts +2 -0
  525. package/dist/sparql/ai/Mcp.mjs +1 -0
  526. package/dist/sparql/ai/Tools.d.mts +2 -0
  527. package/dist/sparql/ai/Tools.mjs +1 -0
  528. package/dist/sparql/ai/index.d.mts +3 -0
  529. package/dist/sparql/ai/index.mjs +3 -0
  530. package/dist/sparql/index.d.mts +30 -0
  531. package/dist/sparql/index.mjs +29 -0
  532. package/dist/sparql/shacl/Evaluator.d.mts +2 -0
  533. package/dist/sparql/shacl/Evaluator.mjs +1 -0
  534. package/dist/sparql/shacl/Query.d.mts +2 -0
  535. package/dist/sparql/shacl/Query.mjs +1 -0
  536. package/dist/sparql/shacl/index.d.mts +3 -0
  537. package/dist/sparql/shacl/index.mjs +3 -0
  538. package/dist/sparql/sql/Dialect.d.mts +2 -0
  539. package/dist/sparql/sql/Dialect.mjs +1 -0
  540. package/dist/sparql/sql/SqlStore.d.mts +2 -0
  541. package/dist/sparql/sql/SqlStore.mjs +1 -0
  542. package/dist/sparql/sql/Translation.d.mts +2 -0
  543. package/dist/sparql/sql/Translation.mjs +1 -0
  544. package/dist/sparql/sql/index.d.mts +4 -0
  545. package/dist/sparql/sql/index.mjs +4 -0
  546. package/dist/stringMap-D5YIpYtR.mjs +38 -0
  547. package/dist/stringMap-D5YIpYtR.mjs.map +1 -0
  548. package/dist/tokens-C6BzeodQ.mjs +24 -0
  549. package/dist/tokens-C6BzeodQ.mjs.map +1 -0
  550. package/dist/turtle/Grammar.d.mts +3 -0
  551. package/dist/turtle/Grammar.mjs +3 -0
  552. package/dist/turtle/Manifest.d.mts +2 -0
  553. package/dist/turtle/Manifest.mjs +1 -0
  554. package/dist/turtle/TriG.d.mts +2 -0
  555. package/dist/turtle/TriG.mjs +1 -0
  556. package/dist/turtle/Turtle.d.mts +2 -0
  557. package/dist/turtle/Turtle.mjs +1 -0
  558. package/dist/turtle/index.d.mts +5 -0
  559. package/dist/turtle/index.mjs +5 -0
  560. package/dist/xmp/DublinCore.d.mts +2 -0
  561. package/dist/xmp/DublinCore.mjs +1 -0
  562. package/dist/xmp/Exif.d.mts +2 -0
  563. package/dist/xmp/Exif.mjs +1 -0
  564. package/dist/xmp/Extract.d.mts +2 -0
  565. package/dist/xmp/Extract.mjs +1 -0
  566. package/dist/xmp/Metadata.d.mts +2 -0
  567. package/dist/xmp/Metadata.mjs +1 -0
  568. package/dist/xmp/Namespaces.d.mts +2 -0
  569. package/dist/xmp/Namespaces.mjs +1 -0
  570. package/dist/xmp/Packet.d.mts +2 -0
  571. package/dist/xmp/Packet.mjs +1 -0
  572. package/dist/xmp/Pdf.d.mts +2 -0
  573. package/dist/xmp/Pdf.mjs +1 -0
  574. package/dist/xmp/PdfA.d.mts +2 -0
  575. package/dist/xmp/PdfA.mjs +1 -0
  576. package/dist/xmp/Photoshop.d.mts +2 -0
  577. package/dist/xmp/Photoshop.mjs +1 -0
  578. package/dist/xmp/Tiff.d.mts +2 -0
  579. package/dist/xmp/Tiff.mjs +1 -0
  580. package/dist/xmp/Xmp.d.mts +2 -0
  581. package/dist/xmp/Xmp.mjs +3 -0
  582. package/dist/xmp/XmpBasic.d.mts +2 -0
  583. package/dist/xmp/XmpBasic.mjs +1 -0
  584. package/dist/xmp/XmpMM.d.mts +2 -0
  585. package/dist/xmp/XmpMM.mjs +1 -0
  586. package/dist/xmp/XmpRights.d.mts +2 -0
  587. package/dist/xmp/XmpRights.mjs +1 -0
  588. package/dist/xmp/index.d.mts +15 -0
  589. package/dist/xmp/index.mjs +15 -0
  590. package/package.json +187 -3
  591. package/src/Dataset.ts +1085 -0
  592. package/src/Iri.ts +322 -0
  593. package/src/Isomorphism.ts +319 -0
  594. package/src/LanguageTag.ts +98 -0
  595. package/src/Namespace.ts +100 -0
  596. package/src/PrefixMap.ts +117 -0
  597. package/src/RdfJs.ts +146 -0
  598. package/src/Rdfs.ts +241 -0
  599. package/src/Reification.ts +103 -0
  600. package/src/Resource.ts +873 -0
  601. package/src/Serialization.ts +775 -0
  602. package/src/Term.ts +1300 -0
  603. package/src/TermCodec.ts +505 -0
  604. package/src/TermJson.ts +313 -0
  605. package/src/Vocab.ts +161 -0
  606. package/src/Xsd.ts +573 -0
  607. package/src/csvw/Csv2Json.ts +265 -0
  608. package/src/csvw/Csv2Rdf.ts +268 -0
  609. package/src/csvw/Datatype.ts +589 -0
  610. package/src/csvw/Metadata.ts +1523 -0
  611. package/src/csvw/Processor.ts +276 -0
  612. package/src/csvw/Report.ts +135 -0
  613. package/src/csvw/Table.ts +759 -0
  614. package/src/csvw/index.ts +22 -0
  615. package/src/csvw/internal/dateFormat.ts +202 -0
  616. package/src/csvw/internal/json.ts +104 -0
  617. package/src/csvw/internal/numberFormat.ts +369 -0
  618. package/src/csvw/internal/object.ts +23 -0
  619. package/src/csvw/internal/uriTemplate.ts +130 -0
  620. package/src/csvw/internal/url.ts +93 -0
  621. package/src/csvw/internal/vocab.ts +282 -0
  622. package/src/index.ts +40 -0
  623. package/src/internal/arbitrary.ts +148 -0
  624. package/src/internal/loop.ts +24 -0
  625. package/src/internal/pending.ts +20 -0
  626. package/src/internal/textDecoder.ts +183 -0
  627. package/src/jsonld/DocumentLoader.ts +512 -0
  628. package/src/jsonld/JsonLd.ts +847 -0
  629. package/src/jsonld/JsonLdError.ts +105 -0
  630. package/src/jsonld/index.ts +13 -0
  631. package/src/jsonld/internal/compact.ts +852 -0
  632. package/src/jsonld/internal/context.ts +781 -0
  633. package/src/jsonld/internal/expand.ts +614 -0
  634. package/src/jsonld/internal/flatten.ts +243 -0
  635. package/src/jsonld/internal/frame.ts +559 -0
  636. package/src/jsonld/internal/iri.ts +52 -0
  637. package/src/jsonld/internal/json.ts +19 -0
  638. package/src/jsonld/internal/linkHeader.ts +60 -0
  639. package/src/jsonld/internal/rdf.ts +481 -0
  640. package/src/jsonld/internal/util.ts +367 -0
  641. package/src/n3/Isomorphism.ts +476 -0
  642. package/src/n3/Mapping.ts +332 -0
  643. package/src/n3/Model.ts +696 -0
  644. package/src/n3/N3.ts +237 -0
  645. package/src/n3/Reasoner.ts +568 -0
  646. package/src/n3/Vocab.ts +111 -0
  647. package/src/n3/index.ts +21 -0
  648. package/src/n3/internal/builtins.ts +668 -0
  649. package/src/n3/internal/guards.ts +23 -0
  650. package/src/n3/internal/lists.ts +106 -0
  651. package/src/n3/internal/loop.ts +28 -0
  652. package/src/n3/internal/parser.ts +1032 -0
  653. package/src/n3/internal/writer.ts +344 -0
  654. package/src/ntriples/Grammar.ts +317 -0
  655. package/src/ntriples/Lexical.ts +321 -0
  656. package/src/ntriples/NQuads.ts +140 -0
  657. package/src/ntriples/NTriples.ts +143 -0
  658. package/src/ntriples/index.ts +14 -0
  659. package/src/ntriples/internal/codec.ts +229 -0
  660. package/src/ntriples/internal/lineParser.ts +326 -0
  661. package/src/ntriples/internal/loop.ts +14 -0
  662. package/src/rdfjson/RdfJson.ts +806 -0
  663. package/src/rdfjson/index.ts +9 -0
  664. package/src/rdfjson/internal/json.ts +19 -0
  665. package/src/rdfxml/RdfXml.ts +1408 -0
  666. package/src/rdfxml/Xml.ts +419 -0
  667. package/src/rdfxml/index.ts +11 -0
  668. package/src/rdfxml/internal/chars.ts +73 -0
  669. package/src/rdfxml/internal/loop.ts +24 -0
  670. package/src/rdfxml/internal/parser.ts +1265 -0
  671. package/src/shacl/Message.ts +102 -0
  672. package/src/shacl/Path.ts +483 -0
  673. package/src/shacl/Shapes.ts +913 -0
  674. package/src/shacl/Sparql.ts +128 -0
  675. package/src/shacl/ValidationReport.ts +438 -0
  676. package/src/shacl/Validator.ts +1156 -0
  677. package/src/shacl/Vocabulary.ts +180 -0
  678. package/src/shacl/index.ts +22 -0
  679. package/src/shacl/internal/compare.ts +128 -0
  680. package/src/shacl/internal/regex.ts +56 -0
  681. package/src/shex/SemAct.ts +197 -0
  682. package/src/shex/ShExC.ts +415 -0
  683. package/src/shex/ShExError.ts +71 -0
  684. package/src/shex/ShExJ.ts +893 -0
  685. package/src/shex/ShExR.ts +640 -0
  686. package/src/shex/ShapeMap.ts +385 -0
  687. package/src/shex/Structure.ts +467 -0
  688. package/src/shex/Validator.ts +395 -0
  689. package/src/shex/index.ts +24 -0
  690. package/src/shex/internal/engine.ts +682 -0
  691. package/src/shex/internal/iterate.ts +14 -0
  692. package/src/shex/internal/json.ts +12 -0
  693. package/src/shex/internal/lexer.ts +56 -0
  694. package/src/shex/internal/nodeConstraint.ts +368 -0
  695. package/src/shex/internal/shexcLexer.ts +387 -0
  696. package/src/shex/internal/shexcParser.ts +1312 -0
  697. package/src/shex/internal/tokens.ts +41 -0
  698. package/src/shex/internal/xpathRegex.ts +290 -0
  699. package/src/sparql/Algebra.ts +914 -0
  700. package/src/sparql/Ast.ts +1344 -0
  701. package/src/sparql/Bindings.ts +272 -0
  702. package/src/sparql/ClientErrors.ts +156 -0
  703. package/src/sparql/ClientFormats.ts +70 -0
  704. package/src/sparql/Engine.ts +699 -0
  705. package/src/sparql/Errors.ts +30 -0
  706. package/src/sparql/Expression.ts +360 -0
  707. package/src/sparql/Federation.ts +187 -0
  708. package/src/sparql/Functions.ts +689 -0
  709. package/src/sparql/Generator.ts +426 -0
  710. package/src/sparql/GraphStore.ts +341 -0
  711. package/src/sparql/Optimizer.ts +230 -0
  712. package/src/sparql/Options.ts +191 -0
  713. package/src/sparql/Parser.ts +173 -0
  714. package/src/sparql/Protocol.ts +342 -0
  715. package/src/sparql/ProtocolErrors.ts +113 -0
  716. package/src/sparql/QueryBuilder.ts +953 -0
  717. package/src/sparql/Results.ts +844 -0
  718. package/src/sparql/ResultsStream.ts +771 -0
  719. package/src/sparql/ServerFormats.ts +75 -0
  720. package/src/sparql/ServiceDescription.ts +130 -0
  721. package/src/sparql/SparqlClient.ts +947 -0
  722. package/src/sparql/SparqlServer.ts +528 -0
  723. package/src/sparql/Store.ts +311 -0
  724. package/src/sparql/TermSchema.ts +20 -0
  725. package/src/sparql/Testing.ts +114 -0
  726. package/src/sparql/Translate.ts +407 -0
  727. package/src/sparql/ai/Mcp.ts +43 -0
  728. package/src/sparql/ai/Tools.ts +481 -0
  729. package/src/sparql/ai/index.ts +11 -0
  730. package/src/sparql/index.ts +64 -0
  731. package/src/sparql/internal/evaluator.ts +947 -0
  732. package/src/sparql/internal/hash.ts +418 -0
  733. package/src/sparql/internal/json.ts +12 -0
  734. package/src/sparql/internal/lexer.ts +488 -0
  735. package/src/sparql/internal/loop.ts +24 -0
  736. package/src/sparql/internal/parser.ts +2215 -0
  737. package/src/sparql/internal/prefetch.ts +46 -0
  738. package/src/sparql/internal/stringMap.ts +39 -0
  739. package/src/sparql/internal/textResults.ts +226 -0
  740. package/src/sparql/internal/values.ts +550 -0
  741. package/src/sparql/shacl/Evaluator.ts +478 -0
  742. package/src/sparql/shacl/Query.ts +574 -0
  743. package/src/sparql/shacl/index.ts +12 -0
  744. package/src/sparql/sql/Dialect.ts +246 -0
  745. package/src/sparql/sql/SqlStore.ts +1080 -0
  746. package/src/sparql/sql/Translation.ts +1898 -0
  747. package/src/sparql/sql/index.ts +17 -0
  748. package/src/sparql/sql/internal/encoding.ts +313 -0
  749. package/src/turtle/Grammar.ts +286 -0
  750. package/src/turtle/Manifest.ts +215 -0
  751. package/src/turtle/TriG.ts +158 -0
  752. package/src/turtle/Turtle.ts +166 -0
  753. package/src/turtle/index.ts +14 -0
  754. package/src/turtle/internal/loop.ts +23 -0
  755. package/src/turtle/internal/parse.ts +112 -0
  756. package/src/turtle/internal/parser.ts +1303 -0
  757. package/src/turtle/internal/serialize.ts +79 -0
  758. package/src/turtle/internal/streamWriter.ts +128 -0
  759. package/src/turtle/internal/writer.ts +898 -0
  760. package/src/xmp/DublinCore.ts +147 -0
  761. package/src/xmp/Exif.ts +109 -0
  762. package/src/xmp/Extract.ts +351 -0
  763. package/src/xmp/Metadata.ts +703 -0
  764. package/src/xmp/Namespaces.ts +228 -0
  765. package/src/xmp/Packet.ts +297 -0
  766. package/src/xmp/Pdf.ts +99 -0
  767. package/src/xmp/PdfA.ts +280 -0
  768. package/src/xmp/Photoshop.ts +275 -0
  769. package/src/xmp/Tiff.ts +196 -0
  770. package/src/xmp/Xmp.ts +430 -0
  771. package/src/xmp/XmpBasic.ts +90 -0
  772. package/src/xmp/XmpMM.ts +82 -0
  773. package/src/xmp/XmpRights.ts +83 -0
  774. package/src/xmp/index.ts +36 -0
  775. package/src/xmp/internal/accessors.ts +72 -0
  776. package/src/xmp/internal/xml.ts +63 -0
@@ -0,0 +1,2215 @@
1
+ /**
2
+ * The SPARQL 1.1 / 1.2 query and update grammar, written with
3
+ * `@thomasfosterau/effect-parse` as a compiled LL(1) grammar over the tokens
4
+ * of `lexer.ts` (whose names are already resolved). It builds the AST
5
+ * directly, expanding every abbreviation and enforcing the static rules of
6
+ * the specification.
7
+ *
8
+ * Three things depend on the order in which the input is read: the labels of
9
+ * generated blank nodes, the scopes of blank node labels, and where
10
+ * aggregates are allowed. They live in a per-parse context, which small
11
+ * hooks (`Parser.make`) update at the points where the reference parser does,
12
+ * and which is reset at the start of every run of the grammar.
13
+ *
14
+ * @internal
15
+ */
16
+ import * as Compiler from '@thomasfosterau/effect-parse/Compiler';
17
+ import * as ParseError from '@thomasfosterau/effect-parse/ParseError';
18
+ import * as Parser from '@thomasfosterau/effect-parse/Parser';
19
+ import * as Token from '@thomasfosterau/effect-parse/Token';
20
+ import * as Term from '../../Term.ts';
21
+ import * as Arr from 'effect/Array';
22
+ import * as Match from 'effect/Match';
23
+ import * as MutableHashSet from 'effect/MutableHashSet';
24
+ import * as Option from 'effect/Option';
25
+ import * as Predicate from 'effect/Predicate';
26
+ import * as Record from 'effect/Record';
27
+ import * as Result from 'effect/Result';
28
+ import * as Ast from '../Ast.ts';
29
+ import { resolve, type Tok, tokenize } from './lexer.ts';
30
+ import { loop } from './loop.ts';
31
+ import * as StringMap from './stringMap.ts';
32
+
33
+ const RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
34
+ const XSD = 'http://www.w3.org/2001/XMLSchema#';
35
+ const rdfType = Term.namedNode(`${RDF}type`);
36
+ const rdfFirst = Term.namedNode(`${RDF}first`);
37
+ const rdfRest = Term.namedNode(`${RDF}rest`);
38
+ const rdfNil = Term.namedNode(`${RDF}nil`);
39
+ const rdfReifies = Term.namedNode(`${RDF}reifies`);
40
+ const xsdInteger = Term.namedNode(`${XSD}integer`);
41
+ const xsdDecimal = Term.namedNode(`${XSD}decimal`);
42
+ const xsdDouble = Term.namedNode(`${XSD}double`);
43
+ const xsdBoolean = Term.namedNode(`${XSD}boolean`);
44
+
45
+ /** A syntax or static error, at a character offset. */
46
+ export class Failure {
47
+ readonly message: string;
48
+ readonly offset: number;
49
+ constructor(message: string, offset: number) {
50
+ this.message = message;
51
+ this.offset = offset;
52
+ }
53
+ }
54
+
55
+ const fail = (message: string, offset: number): never => {
56
+ throw new Failure(message, offset);
57
+ };
58
+
59
+ type P<A> = Parser.Parser<A, Failure, never, ReadonlyArray<Tok>>;
60
+ type Triples = Array<Ast.TriplePattern | Ast.PathPattern>;
61
+
62
+ /**
63
+ * What a hook sees past the last token: a token no grammar rule matches (its
64
+ * kind is no keyword or punctuation), at the end of the input.
65
+ */
66
+ const END: Tok = {
67
+ type: 'END',
68
+ value: '',
69
+ extra: '',
70
+ kind: '',
71
+ start: -1,
72
+ end: -1,
73
+ error: Option.none(),
74
+ };
75
+
76
+ /** The token at `pos`, or `END` past the last one. */
77
+ const tokenAt = (tokens: ReadonlyArray<Tok>, pos: number): Tok => tokens[pos] ?? END;
78
+
79
+ /**
80
+ * A set of token kinds, read through its backing `Map` by the token
81
+ * predicates (one lookup per token, without an `Option` per lookup).
82
+ */
83
+ const kindSet = (kinds: Iterable<string>): ReadonlyMap<string, true> => StringMap.setOf(kinds);
84
+
85
+ /** Whether a triple-shaped item is a triple pattern (not a path pattern). */
86
+ const isTriplePattern = (t: Ast.TriplePattern | Ast.PathPattern): t is Ast.TriplePattern =>
87
+ Predicate.isTagged(t, 'TriplePattern');
88
+
89
+ // -----------------------------------------------------------------------------
90
+ // Per-parse context
91
+ // -----------------------------------------------------------------------------
92
+
93
+ interface TripleContext {
94
+ /** Whether variables are allowed (false for INSERT/DELETE DATA). */
95
+ readonly variables: boolean;
96
+ /** Whether blank nodes are allowed (false for DELETE templates / data). */
97
+ readonly blankNodes: boolean;
98
+ /** Scope identifier for blank node label checks. */
99
+ readonly scope: number;
100
+ /** Label map to check against. */
101
+ readonly labels: Map<string, number>;
102
+ }
103
+
104
+ /** The context outside every pattern (never read: the grammar sets one first). */
105
+ const noContext: TripleContext = {
106
+ variables: true,
107
+ blankNodes: true,
108
+ scope: 0,
109
+ labels: StringMap.empty(),
110
+ };
111
+
112
+ class Context {
113
+ readonly input: string;
114
+ readonly usedLabels: ReadonlyMap<string, true>;
115
+ bnodeCounter = 0;
116
+ scopeCounter = 0;
117
+ opIndex = 0;
118
+ readonly patternLabels = StringMap.empty<number>();
119
+ readonly templateLabels = StringMap.empty<number>();
120
+ aggregatesAllowed = false;
121
+ inAggregate = false;
122
+ /** The aggregate flags saved by `withFlags`, in pairs. */
123
+ readonly flags: Array<boolean> = [];
124
+ /** The triple contexts in force, innermost last. */
125
+ readonly triples: Array<TripleContext> = [];
126
+ /** The last `VERSION` declared. */
127
+ version = Option.none<string>();
128
+ /** Whether the verbs being read are simple predicates, innermost last. */
129
+ readonly verbs: Array<boolean> = [];
130
+ /** The first token of the subject being read. */
131
+ subjectStart: Tok = END;
132
+
133
+ constructor(input: string) {
134
+ this.input = input;
135
+ this.usedLabels = StringMap.setOf(
136
+ Array.from(input.matchAll(/_:([^\s.;,(){}[\]]+)/g), (m) => m[1] ?? ''),
137
+ );
138
+ }
139
+
140
+ get tc(): TripleContext {
141
+ return this.triples[this.triples.length - 1] ?? noContext;
142
+ }
143
+
144
+ patternContext(): TripleContext {
145
+ return {
146
+ variables: true,
147
+ blankNodes: true,
148
+ scope: ++this.scopeCounter,
149
+ labels: this.patternLabels,
150
+ };
151
+ }
152
+
153
+ freshBlankNode(): Term.BlankNode {
154
+ let label = `g${this.bnodeCounter++}`;
155
+ // Skips the labels the input uses.
156
+ loop(() => {
157
+ if (!this.usedLabels.has(label)) return false;
158
+ label = `g${this.bnodeCounter++}`;
159
+ return true;
160
+ });
161
+ return Term.blankNode(label);
162
+ }
163
+ }
164
+
165
+ let ctx: Context = new Context('');
166
+ let fresh: () => Context = () => new Context('');
167
+
168
+ /** Starts a run of the grammar with a new context (the compiled run and any re-run). */
169
+ const start: P<void> = Parser.make<void, Failure, never, ReadonlyArray<Tok>>(() => {
170
+ ctx = fresh();
171
+ return undefined;
172
+ });
173
+
174
+ const offsetOf = (t: Tok): number => (t === END ? ctx.input.length : t.start);
175
+
176
+ /**
177
+ * Runs `f`, returning a thrown `Failure` (a syntax error found while
178
+ * building) as the failure; any other exception is a defect and propagates.
179
+ */
180
+ const catchFailure = <A>(f: () => A): Result.Result<A, Failure> =>
181
+ Result.try({
182
+ try: f,
183
+ catch: (cause) => {
184
+ if (cause instanceof Failure) return cause;
185
+ throw cause;
186
+ },
187
+ });
188
+
189
+ /**
190
+ * A hook: runs `f` on the current token (without consuming it). A `Failure`
191
+ * thrown by `f` is an unrecoverable error.
192
+ */
193
+ const hook = <A>(f: (t: Tok) => A): P<A> =>
194
+ Parser.make<A, Failure, never, ReadonlyArray<Tok>>((state) => {
195
+ try {
196
+ return f(tokenAt(state.input, state.pos));
197
+ } catch (e) {
198
+ if (e instanceof Failure) return state.failCause('Cut', 'Verify', e);
199
+ throw e;
200
+ }
201
+ });
202
+
203
+ /**
204
+ * A token parser written as a hook: `f` returns the value for the current
205
+ * token (consumed), or `None` to fail without consuming it.
206
+ */
207
+ const take = <A>(label: string, f: (t: Tok, next: Tok) => Option.Option<A>): P<A> => {
208
+ const expected = [label];
209
+ return Parser.make<A, Failure, never, ReadonlyArray<Tok>>((state) => {
210
+ const t = state.input[state.pos];
211
+ if (t === undefined || t.type === 'ERROR') return state.backtrack('Token', expected);
212
+ try {
213
+ const a = f(t, tokenAt(state.input, state.pos + 1));
214
+ if (Option.isNone(a)) return state.backtrack('Token', expected);
215
+ state.pos++;
216
+ return a.value;
217
+ } catch (e) {
218
+ if (e instanceof Failure) return state.failCause('Cut', 'Verify', e);
219
+ throw e;
220
+ }
221
+ });
222
+ };
223
+
224
+ /** A `take` result: the token is taken. */
225
+ const taken = Option.some(true);
226
+ const notTaken = Option.none();
227
+
228
+ /**
229
+ * Runs `p` with the aggregate flags set (`inAggregate` left alone when
230
+ * `None`), restoring them afterwards.
231
+ */
232
+ const withFlags = <A>(
233
+ aggregatesAllowed: boolean,
234
+ inAggregate: Option.Option<boolean>,
235
+ p: P<A>,
236
+ ): P<A> =>
237
+ Parser.delimited(
238
+ hook(() => {
239
+ ctx.flags.push(ctx.aggregatesAllowed, ctx.inAggregate);
240
+ ctx.aggregatesAllowed = aggregatesAllowed;
241
+ if (Option.isSome(inAggregate)) ctx.inAggregate = inAggregate.value;
242
+ }),
243
+ p,
244
+ hook(() => {
245
+ // The flags were pushed in pairs just above.
246
+ ctx.inAggregate = ctx.flags.pop() ?? false;
247
+ ctx.aggregatesAllowed = ctx.flags.pop() ?? false;
248
+ }),
249
+ );
250
+
251
+ /** Runs `p` in a triple context, restoring the enclosing one afterwards. */
252
+ const inContext = <A>(make: () => TripleContext, p: P<A>): P<A> =>
253
+ Parser.delimited(
254
+ hook(() => {
255
+ ctx.triples.push(make());
256
+ }),
257
+ p,
258
+ hook(() => {
259
+ ctx.triples.pop();
260
+ }),
261
+ );
262
+
263
+ // -----------------------------------------------------------------------------
264
+ // Token parsers
265
+ // -----------------------------------------------------------------------------
266
+
267
+ const describe = (t: Tok): string =>
268
+ t === END
269
+ ? 'end of input'
270
+ : t.type === 'STRING'
271
+ ? 'string literal'
272
+ : `'${ctx.input.slice(t.start, t.end)}'`;
273
+
274
+ const unexpected = (t: Tok, expected?: string): never =>
275
+ fail(
276
+ `Unexpected ${describe(t)}${expected !== undefined ? `, expected ${expected}` : ''}`,
277
+ offsetOf(t),
278
+ );
279
+
280
+ /** The reference parser's "Unexpected …" error at `t` (or the lexer's, at an error token). */
281
+ const unexpectedAt = (t: Tok, expected?: string): never =>
282
+ t.type === 'ERROR' ? fail(t.value, t.start) : unexpected(t, expected);
283
+
284
+ /** Fails with the reference parser's "Unexpected …" message at the current token. */
285
+ const unexpectedHere = <A = never>(expected?: string): P<A> =>
286
+ hook((t): A => unexpectedAt(t, expected));
287
+
288
+ /**
289
+ * A token of the given kind (see `Tok.kind`). A token set rather than a
290
+ * `Parser.make` hook, so the compiler inlines the match instead of calling
291
+ * back into an interpreted step.
292
+ */
293
+ const tok = (kind: string): P<Tok> =>
294
+ Token.oneOf<ReadonlyArray<Tok>>((t) => t.kind === kind).pipe(Parser.expected(`'${kind}'`));
295
+
296
+ /** `kind`, or the "Unexpected …, expected …" error. */
297
+ const expect = (
298
+ kind: string,
299
+ label = kind === kind.toUpperCase() && /^[A-Z]/.test(kind) ? kind : `'${kind}'`,
300
+ ): P<Tok> => Parser.alt(tok(kind), unexpectedHere<Tok>(label));
301
+
302
+ /** Whether the next token is of kind `kind` (consumed if so). */
303
+ const eat = (kind: string): P<boolean> => Parser.opt(tok(kind)).pipe(Parser.map(Option.isSome));
304
+
305
+ /**
306
+ * Whether the next token's kind is one of `kinds` (not consumed). A peeked
307
+ * token set, like `tok`, so the compiler inlines it.
308
+ */
309
+ const peekKind = (kinds: ReadonlyArray<string>): P<void> => {
310
+ const set = kindSet(kinds);
311
+ return Parser.peek(Token.oneOf<ReadonlyArray<Tok>>((t) => set.has(t.kind))).pipe(
312
+ Parser.asVoid,
313
+ Parser.expected(kinds.map((k) => `'${k}'`).join(' or ')),
314
+ );
315
+ };
316
+
317
+ /** Any token but a lexer error token (consumed). A token set, like `tok`. */
318
+ const anyToken: P<Tok> = Token.oneOf<ReadonlyArray<Tok>>((t) => t.type !== 'ERROR').pipe(
319
+ Parser.expected('a token'),
320
+ );
321
+
322
+ /**
323
+ * Chooses a parser by the kind of the next token; when no case matches,
324
+ * `otherwise` (or a failure that consumes nothing).
325
+ */
326
+ const select = <A, B = A>(
327
+ cases: ReadonlyArray<readonly [ReadonlyArray<string>, P<A>]>,
328
+ otherwise?: P<B>,
329
+ ): P<A | B> => {
330
+ // Guarded alternatives rather than `Parser.dispatch`, whose cases the JIT
331
+ // leaves to the (slower) closure backend.
332
+ const seen = MutableHashSet.empty<string>();
333
+ const branches: Array<P<A | B>> = Arr.filterMap(cases, ([kinds, p]) => {
334
+ const own = Arr.dedupe(kinds.filter((k) => !MutableHashSet.has(seen, k)));
335
+ own.forEach((k) => MutableHashSet.add(seen, k));
336
+ return Arr.isArrayNonEmpty(own)
337
+ ? Result.succeed(Parser.preceded(peekKind(own), p))
338
+ : Result.failVoid;
339
+ });
340
+ if (otherwise !== undefined) branches.push(otherwise);
341
+ return Parser.alt(...branches);
342
+ };
343
+
344
+ /** Whether the next tokens are `a` then `b` (not consumed). */
345
+ const peek2 = (a: string, b: string): P<unknown> => Parser.peek(Parser.seq(tok(a), tok(b)));
346
+
347
+ const nil: P<unknown> = peek2('(', ')');
348
+ const anon: P<unknown> = peek2('[', ']');
349
+
350
+ const iri: P<Term.NamedNode> = take('an IRI', (t) => {
351
+ if (t.type === 'IRI') return Option.some(Term.namedNode(t.value));
352
+ if (t.type === 'PNAME')
353
+ return Option.isSome(t.error)
354
+ ? fail(t.error.value, t.start)
355
+ : Option.some(Term.namedNode(t.value));
356
+ return notTaken;
357
+ });
358
+
359
+ const iriOrError: P<Term.NamedNode> = Parser.alt(iri, unexpectedHere<Term.NamedNode>('an IRI'));
360
+
361
+ const variable: P<Term.Variable> = take('a variable', (t) =>
362
+ t.type === 'VAR' ? Option.some(Term.variable(t.value)) : notTaken,
363
+ );
364
+
365
+ const variableOrError: P<Term.Variable> = Parser.alt(
366
+ variable,
367
+ unexpectedHere<Term.Variable>('a variable'),
368
+ );
369
+
370
+ /** A variable in a pattern (checked against the triple context). */
371
+ const patternVariable: P<Term.Variable> = take('a variable', (t) => {
372
+ if (t.type !== 'VAR') return notTaken;
373
+ if (!ctx.tc.variables) fail('Variables are not allowed here', t.start);
374
+ return Option.some(Term.variable(t.value));
375
+ });
376
+
377
+ const isIri = (t: Tok): boolean => t.type === 'IRI' || t.type === 'PNAME';
378
+ const isNumber = (t: Tok): boolean =>
379
+ t.type === 'INTEGER' || t.type === 'DECIMAL' || t.type === 'DOUBLE';
380
+
381
+ const blankNodeLabel: P<Term.BlankNode> = take('a blank node', (t) => {
382
+ if (t.type !== 'BNODE') return notTaken;
383
+ const tc = ctx.tc;
384
+ if (!tc.blankNodes) fail('Blank nodes are not allowed here', t.start);
385
+ const existing = tc.labels.get(t.value);
386
+ if (existing !== undefined && existing !== tc.scope) {
387
+ fail(`Blank node label _:${t.value} is used in more than one scope`, t.start);
388
+ }
389
+ tc.labels.set(t.value, tc.scope);
390
+ return Option.some(Term.blankNode(t.value));
391
+ });
392
+
393
+ /** A generated blank node in a pattern (checked against the triple context). */
394
+ const freshPatternBlankNode: P<Term.BlankNode> = hook((t) => {
395
+ if (!ctx.tc.blankNodes) fail('Blank nodes are not allowed here', offsetOf(t));
396
+ return ctx.freshBlankNode();
397
+ });
398
+
399
+ const string: P<Tok> = take('a string', (t) => (t.type === 'STRING' ? Option.some(t) : notTaken));
400
+
401
+ const isDirection = (direction: string): direction is Term.Direction =>
402
+ direction === 'ltr' || direction === 'rtl';
403
+
404
+ /** A literal's `@tag` suffix, with its `--direction` if any. */
405
+ interface LanguageSuffix {
406
+ readonly tag: string;
407
+ readonly direction: Option.Option<Term.Direction>;
408
+ }
409
+
410
+ const rdfLiteral: P<Term.Literal> = Parser.seq(
411
+ string,
412
+ Parser.alt(
413
+ take('a language tag', (t, next): Option.Option<LanguageSuffix> => {
414
+ if (t.type !== 'LANGTAG') return notTaken;
415
+ const tag = t.value;
416
+ const i = tag.indexOf('--');
417
+ if (i === -1) return Option.some({ tag, direction: Option.none() });
418
+ const direction = tag.slice(i + 2).toLowerCase();
419
+ return isDirection(direction)
420
+ ? Option.some({ tag: tag.slice(0, i), direction: Option.some(direction) })
421
+ : fail(`Invalid base direction '${direction}'`, offsetOf(next));
422
+ }),
423
+ Parser.preceded(tok('^^'), iriOrError),
424
+ Parser.succeed(undefined),
425
+ ),
426
+ ).pipe(
427
+ Parser.map(([s, suffix]): Term.Literal => {
428
+ if (suffix === undefined) return Term.literal(s.value);
429
+ if (suffix instanceof Term.NamedNode) return Term.literal(s.value, suffix);
430
+ return Option.isSome(suffix.direction)
431
+ ? Term.literal(s.value, { language: suffix.tag, direction: suffix.direction.value })
432
+ : Term.literal(s.value, suffix.tag);
433
+ }),
434
+ );
435
+
436
+ const numberLiteral = (t: Tok, sign: string): Term.Literal =>
437
+ Term.literal(
438
+ sign + t.value,
439
+ t.type === 'INTEGER' ? xsdInteger : t.type === 'DECIMAL' ? xsdDecimal : xsdDouble,
440
+ );
441
+
442
+ const numericLiteral: P<Term.Literal> = take('a number', (t) =>
443
+ isNumber(t) ? Option.some(numberLiteral(t, '')) : notTaken,
444
+ );
445
+
446
+ /** `+` or `-` immediately followed by a number. */
447
+ const signedNumber: P<Term.Literal> = Parser.make<Term.Literal, Failure, never, ReadonlyArray<Tok>>(
448
+ (state) => {
449
+ const t = state.input[state.pos];
450
+ const n = state.input[state.pos + 1];
451
+ if (
452
+ t !== undefined &&
453
+ (t.kind === '+' || t.kind === '-') &&
454
+ n !== undefined &&
455
+ n.start === t.end &&
456
+ isNumber(n)
457
+ ) {
458
+ state.pos += 2;
459
+ return numberLiteral(n, t.value);
460
+ }
461
+ return state.backtrack('Token', ['a number']);
462
+ },
463
+ );
464
+
465
+ const booleanLiteral: P<Term.Literal> = take('a boolean', (t) =>
466
+ t.kind === 'TRUE' || t.kind === 'FALSE'
467
+ ? Option.some(Term.literal(t.value.toLowerCase(), xsdBoolean))
468
+ : notTaken,
469
+ );
470
+
471
+ /** `a`, or an IRI. */
472
+ const aOrIri: P<Term.NamedNode> = Parser.alt(tok('a').pipe(Parser.as(rdfType)), iriOrError);
473
+
474
+ // -----------------------------------------------------------------------------
475
+ // Data terms
476
+ // -----------------------------------------------------------------------------
477
+
478
+ /** iri | RDFLiteral | NumericLiteral | BooleanLiteral */
479
+ const dataTerm: P<Term.NamedNode | Term.Literal> = Parser.alt(
480
+ iri,
481
+ rdfLiteral,
482
+ numericLiteral,
483
+ signedNumber,
484
+ booleanLiteral,
485
+ unexpectedHere<Term.Literal>('an RDF term'),
486
+ );
487
+
488
+ const tripleTermData: P<Term.Triple> = Parser.preceded(
489
+ tok('<<('),
490
+ Parser.seq(
491
+ iriOrError,
492
+ aOrIri,
493
+ Parser.alt(
494
+ Parser.suspend(() => tripleTermData),
495
+ dataTerm,
496
+ ),
497
+ expect(')>>'),
498
+ ),
499
+ ).pipe(Parser.map(([s, p, o]) => Term.triple(s, p, o)));
500
+
501
+ /** A data block value; `None` for `UNDEF`. */
502
+ const dataBlockValue: P<Option.Option<Term.GroundTerm>> = Parser.alt(
503
+ tok('UNDEF').pipe(Parser.as(Option.none())),
504
+ Parser.alt(tripleTermData, dataTerm).pipe(Parser.map(Option.some)),
505
+ );
506
+
507
+ const dataBlock: P<Ast.ValuesPattern> = Parser.alt(
508
+ Parser.seq(
509
+ variable,
510
+ Parser.preceded(
511
+ expect('{'),
512
+ Parser.terminated(
513
+ Parser.repeat(Parser.preceded(Parser.not(tok('}')), dataBlockValue)),
514
+ tok('}'),
515
+ ),
516
+ ),
517
+ ).pipe(
518
+ Parser.map(([v, values]) =>
519
+ Ast.values(
520
+ [v],
521
+ values.map((x) => [Option.getOrUndefined(x)]),
522
+ ),
523
+ ),
524
+ ),
525
+ Parser.seq(
526
+ Parser.preceded(
527
+ expect('('),
528
+ Parser.repeat(
529
+ Parser.seq(
530
+ variable,
531
+ hook((t) => t),
532
+ ),
533
+ ).pipe(
534
+ Parser.tryMap((vars) =>
535
+ Option.match(
536
+ // The first variable that an earlier one repeats.
537
+ Arr.findFirst(vars, ([v], i) => vars.findIndex(([x]) => x.value === v.value) < i),
538
+ {
539
+ onNone: () => Result.succeed(vars.map(([v]) => v)),
540
+ onSome: ([v, next]) =>
541
+ Result.fail(
542
+ new Failure(`Duplicate variable ?${v.value} in VALUES`, offsetOf(next)),
543
+ ),
544
+ },
545
+ ),
546
+ ),
547
+ Parser.cut,
548
+ ),
549
+ ),
550
+ Parser.preceded(
551
+ Parser.seq(expect(')'), expect('{')),
552
+ Parser.terminated(
553
+ Parser.repeat(
554
+ Parser.preceded(
555
+ Parser.not(tok('}')),
556
+ Parser.seq(
557
+ hook((t) => offsetOf(t)),
558
+ Parser.preceded(
559
+ expect('('),
560
+ Parser.terminated(
561
+ Parser.repeat(Parser.preceded(Parser.not(tok(')')), dataBlockValue)),
562
+ anyToken,
563
+ ),
564
+ ),
565
+ ),
566
+ ),
567
+ ),
568
+ expect('}'),
569
+ ),
570
+ ),
571
+ ).pipe(
572
+ Parser.tryMap(([variables, rows]) =>
573
+ Option.match(
574
+ Arr.findFirst(rows, ([, row]) => row.length !== variables.length),
575
+ {
576
+ onNone: () =>
577
+ Result.succeed(
578
+ Ast.values(
579
+ variables,
580
+ rows.map(([, row]) => row.map(Option.getOrUndefined)),
581
+ ),
582
+ ),
583
+ onSome: ([at, row]) =>
584
+ Result.fail(
585
+ new Failure(
586
+ `VALUES row has ${row.length} values but ${variables.length} variables`,
587
+ at,
588
+ ),
589
+ ),
590
+ },
591
+ ),
592
+ ),
593
+ Parser.cut,
594
+ ),
595
+ );
596
+
597
+ // -----------------------------------------------------------------------------
598
+ // Triples
599
+ // -----------------------------------------------------------------------------
600
+
601
+ interface Node {
602
+ readonly term: Ast.TermPattern;
603
+ /** The triples the node expands to, in the order the reference parser emits them. */
604
+ readonly triples: Triples;
605
+ }
606
+
607
+ const node = (term: Ast.TermPattern, triples: Triples = []): Node => ({ term, triples });
608
+
609
+ interface Verb {
610
+ readonly predicate: Ast.VarOrIri | Ast.Path;
611
+ readonly simple: boolean;
612
+ }
613
+
614
+ /** `~ r` (and its `{| … |}`), or a `{| … |}` with a generated reifier. */
615
+ interface Annotation {
616
+ readonly reifier: Ast.TermPattern;
617
+ readonly block: Option.Option<PropertyList>;
618
+ }
619
+
620
+ interface Obj {
621
+ readonly node: Node;
622
+ readonly annotation: ReadonlyArray<Annotation>;
623
+ }
624
+
625
+ /** A property list as read; `build` expands it once its subject is known. */
626
+ type PropertyList = ReadonlyArray<readonly [Verb, ReadonlyArray<Obj>]>;
627
+
628
+ /** The triples of a property list, in the order the reference parser emits them. */
629
+ const build = (subject: Ast.TermPattern, pl: PropertyList, out: Triples = []): Triples => {
630
+ pl.forEach(([v, objects]) => {
631
+ const predicate = v.predicate;
632
+ objects.forEach(({ node: o, annotation }) => {
633
+ o.triples.forEach((t) => out.push(t));
634
+ if (Ast.isPath(predicate)) {
635
+ out.push(Ast.pathPattern(subject, predicate, o.term));
636
+ return;
637
+ }
638
+ out.push(Ast.triplePattern(subject, predicate, o.term));
639
+ if (Arr.isReadonlyArrayEmpty(annotation)) return;
640
+ const triple = Term.triple<any, any, any>(subject, predicate, o.term);
641
+ annotation.forEach((a) => {
642
+ out.push(Ast.triplePattern(a.reifier, rdfReifies, triple));
643
+ if (Option.isSome(a.block)) build(a.reifier, a.block.value, out);
644
+ });
645
+ });
646
+ });
647
+ return out;
648
+ };
649
+
650
+ /** The token types that start a triples block on their own. */
651
+ const TRIPLES_START = kindSet([
652
+ 'VAR',
653
+ 'IRI',
654
+ 'PNAME',
655
+ 'BNODE',
656
+ 'STRING',
657
+ 'INTEGER',
658
+ 'DECIMAL',
659
+ 'DOUBLE',
660
+ ]);
661
+
662
+ /** Whether a token can start a triples block. A plain branch per type: it runs once per peek. */
663
+ const startsTriplesToken = (t: Tok, next: Tok): boolean => {
664
+ if (TRIPLES_START.has(t.type)) return true;
665
+ if (t.type === 'WORD') return t.kind === 'TRUE' || t.kind === 'FALSE';
666
+ if (t.type !== 'PUNCT') return false;
667
+ const v = t.value;
668
+ return (
669
+ v === '(' ||
670
+ v === '[' ||
671
+ v === '<<' ||
672
+ v === '<<(' ||
673
+ ((v === '+' || v === '-') && isNumber(next))
674
+ );
675
+ };
676
+
677
+ const startsTriples: P<unknown> = Parser.peek(
678
+ take('triples', (t, next) => (startsTriplesToken(t, next) ? taken : notTaken)),
679
+ );
680
+
681
+ /** The triples productions, with or without property paths. */
682
+ interface TriplesGrammar {
683
+ readonly triplesSameSubject: P<Triples>;
684
+ readonly triplesBlock: P<readonly [Triples, boolean]>;
685
+ readonly triplesTemplate: P<Triples>;
686
+ }
687
+
688
+ const path: P<Ast.Path> = Parser.suspend(() => pathDef);
689
+
690
+ const triplesGrammar = (paths: boolean): TriplesGrammar => {
691
+ const graphNode: P<Node> = Parser.suspend(() => graphNodeDef);
692
+ const propertyList: P<PropertyList> = Parser.suspend(() => propertyListDef);
693
+
694
+ const varOrTerm = (allowNil: boolean): P<Ast.TermPattern> =>
695
+ Parser.alt(
696
+ patternVariable,
697
+ iri,
698
+ blankNodeLabel,
699
+ rdfLiteral,
700
+ numericLiteral,
701
+ booleanLiteral,
702
+ signedNumber,
703
+ ...(allowNil
704
+ ? [Parser.preceded(Parser.seq(nil, anyToken, anyToken), Parser.succeed(rdfNil))]
705
+ : []),
706
+ Parser.preceded(Parser.seq(anon, anyToken, anyToken), freshPatternBlankNode),
707
+ Parser.suspend(() => tripleTerm),
708
+ unexpectedHere<Ast.TermPattern>('an RDF term or variable'),
709
+ );
710
+
711
+ const patternPredicate: P<Ast.VarOrIri> = Parser.alt(patternVariable, aOrIri);
712
+
713
+ const tripleTermComponent: P<Ast.TermPattern> = Parser.alt(
714
+ Parser.suspend(() => tripleTerm),
715
+ Parser.preceded(
716
+ Parser.peek(Parser.alt(tok('('), tok('<<'), Parser.preceded(Parser.not(anon), tok('[')))),
717
+ unexpectedHere<Ast.TermPattern>(),
718
+ ),
719
+ varOrTerm(false),
720
+ );
721
+
722
+ const tripleTerm: P<Ast.TermPattern> = Parser.preceded(
723
+ tok('<<('),
724
+ Parser.seq(tripleTermComponent, patternPredicate, tripleTermComponent, expect(')>>')),
725
+ ).pipe(Parser.map(([s, p, o]) => Term.triple<any, any, any>(s, p, o)));
726
+
727
+ const reifier: P<Ast.TermPattern> = Parser.preceded(
728
+ tok('~'),
729
+ Parser.alt(
730
+ patternVariable,
731
+ iri,
732
+ blankNodeLabel,
733
+ Parser.preceded(Parser.seq(anon, anyToken, anyToken), freshPatternBlankNode),
734
+ freshPatternBlankNode,
735
+ ),
736
+ );
737
+
738
+ const reifiedTriple: P<Node> = Parser.suspend(() => reifiedTripleDef);
739
+
740
+ const reifiedTripleComponent: P<Node> = Parser.alt(
741
+ reifiedTriple,
742
+ Parser.suspend(() => tripleTerm).pipe(Parser.map((t) => node(t))),
743
+ Parser.preceded(
744
+ Parser.peek(Parser.alt(tok('('), Parser.preceded(Parser.not(anon), tok('[')))),
745
+ unexpectedHere<Node>(),
746
+ ),
747
+ varOrTerm(false).pipe(Parser.map((t) => node(t))),
748
+ );
749
+
750
+ const reifiedTripleDef: P<Node> = Parser.preceded(
751
+ tok('<<'),
752
+ Parser.seq(
753
+ reifiedTripleComponent,
754
+ patternPredicate,
755
+ reifiedTripleComponent,
756
+ Parser.alt(reifier, freshPatternBlankNode),
757
+ expect('>>'),
758
+ ),
759
+ ).pipe(
760
+ Parser.map(([s, p, o, r]) =>
761
+ node(r, [
762
+ ...s.triples,
763
+ ...o.triples,
764
+ Ast.triplePattern(r, rdfReifies, Term.triple<any, any, any>(s.term, p, o.term)),
765
+ ]),
766
+ ),
767
+ );
768
+
769
+ const triplesNode: P<Node> = Parser.alt(
770
+ Parser.preceded(
771
+ tok('['),
772
+ Parser.seq(freshPatternBlankNode, Parser.terminated(propertyList, expect(']'))),
773
+ ).pipe(Parser.map(([b, pl]) => node(b, build(b, pl)))),
774
+ Parser.preceded(
775
+ tok('('),
776
+ Parser.seq(
777
+ Parser.terminated(
778
+ Parser.repeat(Parser.preceded(Parser.not(tok(')')), graphNode)),
779
+ anyToken,
780
+ ),
781
+ hook((t) => t),
782
+ ),
783
+ ).pipe(
784
+ Parser.map(([items, t]) => {
785
+ if (!Arr.isArrayNonEmpty(items)) return node(rdfNil);
786
+ if (!ctx.tc.blankNodes) fail('Blank nodes are not allowed here', offsetOf(t));
787
+ // Each item with the blank node of its list cell.
788
+ const cells = Arr.map(items, (item) => [ctx.freshBlankNode(), item] as const);
789
+ const triples: Triples = [];
790
+ items.forEach((item) => item.triples.forEach((x) => triples.push(x)));
791
+ cells.forEach(([cell, item], i) => {
792
+ triples.push(Ast.triplePattern(cell, rdfFirst, item.term));
793
+ triples.push(Ast.triplePattern(cell, rdfRest, cells[i + 1]?.[0] ?? rdfNil));
794
+ });
795
+ return node(cells[0][0], triples);
796
+ }),
797
+ ),
798
+ );
799
+
800
+ /** GraphNode / GraphNodePath */
801
+ const graphNodeDef: P<Node> = Parser.alt(
802
+ reifiedTriple,
803
+ Parser.preceded(
804
+ Parser.alt(
805
+ Parser.seq(Parser.not(nil), Parser.peek(tok('('))),
806
+ Parser.seq(Parser.not(anon), Parser.peek(tok('['))),
807
+ ),
808
+ triplesNode,
809
+ ),
810
+ varOrTerm(true).pipe(Parser.map((t) => node(t))),
811
+ );
812
+
813
+ const startsVerb: P<unknown> = Parser.peek(
814
+ take('a verb', (t) =>
815
+ t.type === 'VAR' ||
816
+ isIri(t) ||
817
+ t.kind === 'a' ||
818
+ (paths && (t.kind === '^' || t.kind === '!' || t.kind === '('))
819
+ ? taken
820
+ : notTaken,
821
+ ),
822
+ );
823
+
824
+ /** A verb; whether it is simple is pushed on `ctx.verbs` until its objects are read. */
825
+ const verb: P<Verb> = Parser.alt(
826
+ Parser.seq(
827
+ patternVariable,
828
+ paths
829
+ ? Parser.preceded(Parser.peek(Parser.alt(tok('/'), tok('|'))), unexpectedHere<void>()).pipe(
830
+ Parser.opt,
831
+ )
832
+ : Parser.succeed(undefined),
833
+ ).pipe(Parser.map(([v]): Verb => ({ predicate: v, simple: true }))),
834
+ paths
835
+ ? path.pipe(
836
+ Parser.map((p): Verb =>
837
+ Predicate.isTagged(p, 'PathLink')
838
+ ? { predicate: p.iri, simple: true }
839
+ : { predicate: p, simple: false },
840
+ ),
841
+ )
842
+ : aOrIri.pipe(Parser.map((predicate): Verb => ({ predicate, simple: true }))),
843
+ ).pipe(
844
+ Parser.map((v) => {
845
+ ctx.verbs.push(v.simple);
846
+ return v;
847
+ }),
848
+ );
849
+
850
+ const annotationBlock: P<PropertyList> = Parser.terminated(propertyList, expect('|}'));
851
+
852
+ // `~ r` names a reifier and `{| … |}` annotates it (a fresh one if none was named).
853
+ const annotationItem: P<Annotation> = Parser.alt(
854
+ Parser.seq(reifier, Parser.opt(Parser.preceded(tok('{|'), annotationBlock))).pipe(
855
+ Parser.map(([r, block]): Annotation => ({ reifier: r, block })),
856
+ ),
857
+ Parser.preceded(tok('{|'), Parser.seq(freshPatternBlankNode, annotationBlock)).pipe(
858
+ Parser.map(([r, block]): Annotation => ({ reifier: r, block: Option.some(block) })),
859
+ ),
860
+ );
861
+
862
+ const annotation: P<ReadonlyArray<Annotation>> = Parser.alt(
863
+ Parser.preceded(
864
+ Parser.seq(
865
+ Parser.peek(Parser.alt(tok('~'), tok('{|'))),
866
+ hook((t) => {
867
+ if (!ctx.verbs[ctx.verbs.length - 1]) {
868
+ fail('Reifiers and annotations require a simple predicate', offsetOf(t));
869
+ }
870
+ }),
871
+ ),
872
+ Parser.repeat(annotationItem, { min: 1 }),
873
+ ),
874
+ Parser.succeed([]),
875
+ );
876
+
877
+ const objectList: P<ReadonlyArray<Obj>> = Parser.separated(
878
+ Parser.seq(graphNode, annotation).pipe(
879
+ Parser.map(([n, a]): Obj => ({ node: n, annotation: a })),
880
+ ),
881
+ tok(','),
882
+ { min: 1 },
883
+ );
884
+
885
+ const verbObjects: P<readonly [Verb, ReadonlyArray<Obj>]> = Parser.seq(
886
+ verb,
887
+ Parser.terminated(
888
+ objectList,
889
+ hook(() => {
890
+ ctx.verbs.pop();
891
+ }),
892
+ ),
893
+ );
894
+
895
+ const propertyListDef: P<PropertyList> = Parser.seq(
896
+ verbObjects,
897
+ Parser.repeat(
898
+ Parser.preceded(
899
+ Parser.repeat(tok(';'), { min: 1 }),
900
+ Parser.preceded(startsVerb, verbObjects),
901
+ ),
902
+ ),
903
+ Parser.opt(Parser.repeat(tok(';'), { min: 1 })),
904
+ ).pipe(Parser.map(([first, rest]) => [first, ...rest]));
905
+
906
+ const withProperties = (subject: P<Node>): P<Triples> =>
907
+ Parser.seq(subject, Parser.opt(Parser.preceded(startsVerb, propertyList))).pipe(
908
+ Parser.map(([s, pl]) =>
909
+ Option.isSome(pl) ? build(s.term, pl.value, [...s.triples]) : s.triples,
910
+ ),
911
+ );
912
+
913
+ const triplesSameSubject: P<Triples> = Parser.alt(
914
+ withProperties(reifiedTriple),
915
+ Parser.preceded(
916
+ Parser.alt(
917
+ Parser.seq(Parser.not(nil), Parser.peek(tok('('))),
918
+ Parser.seq(Parser.not(anon), Parser.peek(tok('['))),
919
+ ),
920
+ withProperties(triplesNode),
921
+ ),
922
+ Parser.seq(
923
+ hook((t) => {
924
+ ctx.subjectStart = t;
925
+ }),
926
+ varOrTerm(true),
927
+ Parser.alt(
928
+ Parser.preceded(startsVerb, propertyList),
929
+ hook((t): PropertyList =>
930
+ unexpectedAt(t, `a predicate after ${describe(ctx.subjectStart)}`),
931
+ ),
932
+ ),
933
+ ).pipe(Parser.map(([, subject, pl]) => build(subject, pl))),
934
+ );
935
+
936
+ /** TriplesBlock: the triples, and whether it ended with a '.' */
937
+ const triplesBlock: P<readonly [Triples, boolean]> = Parser.seq(
938
+ triplesSameSubject,
939
+ Parser.repeat(Parser.preceded(Parser.seq(tok('.'), startsTriples), triplesSameSubject)),
940
+ eat('.'),
941
+ ).pipe(Parser.map(([first, rest, dot]) => [[...first, ...rest.flat()], dot] as const));
942
+
943
+ /** TriplesTemplate / ConstructTriples (no paths); stops before `}`. */
944
+ const triplesTemplate: P<Triples> = Parser.opt(
945
+ Parser.preceded(
946
+ Parser.seq(Parser.not(tok('}')), startsTriples),
947
+ Parser.seq(
948
+ triplesSameSubject,
949
+ Parser.repeat(
950
+ Parser.preceded(
951
+ Parser.seq(tok('.'), Parser.not(tok('}')), startsTriples),
952
+ triplesSameSubject,
953
+ ),
954
+ ),
955
+ eat('.'),
956
+ ),
957
+ ),
958
+ ).pipe(Parser.map((o) => (Option.isNone(o) ? [] : [...o.value[0], ...o.value[1].flat()])));
959
+
960
+ return { triplesSameSubject, triplesBlock, triplesTemplate };
961
+ };
962
+
963
+ // -----------------------------------------------------------------------------
964
+ // Property paths
965
+ // -----------------------------------------------------------------------------
966
+
967
+ const negatedOne: P<readonly [boolean, Term.NamedNode]> = Parser.seq(eat('^'), aOrIri);
968
+
969
+ const negated: P<Ast.Path> = Parser.alt(
970
+ Parser.preceded(
971
+ tok('('),
972
+ Parser.terminated(Parser.opt(Parser.separated(negatedOne, tok('|'), { min: 1 })), expect(')')),
973
+ ).pipe(Parser.map((o) => Option.getOrElse(o, () => []))),
974
+ negatedOne.pipe(Parser.map((one) => [one])),
975
+ ).pipe(
976
+ Parser.map((ones) =>
977
+ Ast.negated(
978
+ ones.filter(([inv]) => !inv).map(([, i]) => i),
979
+ ones.filter(([inv]) => inv).map(([, i]) => i),
980
+ ),
981
+ ),
982
+ );
983
+
984
+ const pathPrimary: P<Ast.Path> = Parser.alt(
985
+ tok('a').pipe(Parser.as(Ast.link(rdfType))),
986
+ iri.pipe(Parser.map((i) => Ast.link(i))),
987
+ Parser.preceded(tok('!'), negated),
988
+ Parser.delimited(tok('('), path, expect(')')),
989
+ unexpectedHere<Ast.Path>('a property path'),
990
+ );
991
+
992
+ const pathElt: P<Ast.Path> = Parser.seq(
993
+ pathPrimary,
994
+ Parser.opt(Parser.alt(tok('?'), tok('*'), tok('+'))),
995
+ ).pipe(
996
+ Parser.map(([primary, mod]) =>
997
+ Option.isNone(mod)
998
+ ? primary
999
+ : mod.value.kind === '?'
1000
+ ? Ast.zeroOrOne(primary)
1001
+ : mod.value.kind === '*'
1002
+ ? Ast.zeroOrMore(primary)
1003
+ : Ast.oneOrMore(primary),
1004
+ ),
1005
+ );
1006
+
1007
+ const pathEltOrInverse: P<Ast.Path> = Parser.alt(
1008
+ Parser.preceded(tok('^'), pathElt).pipe(Parser.map((p) => Ast.inverse(p))),
1009
+ pathElt,
1010
+ );
1011
+
1012
+ const pathSequence: P<Ast.Path> = Parser.separated(pathEltOrInverse, tok('/'), { min: 1 }).pipe(
1013
+ Parser.map((ps) => (ps.length === 1 ? ps[0] : Ast.sequence(...ps))),
1014
+ );
1015
+
1016
+ const pathDef: P<Ast.Path> = Parser.separated(pathSequence, tok('|'), { min: 1 }).pipe(
1017
+ Parser.map((ps) => (ps.length === 1 ? ps[0] : Ast.alternative(...ps))),
1018
+ );
1019
+
1020
+ // -----------------------------------------------------------------------------
1021
+ // Expressions
1022
+ // -----------------------------------------------------------------------------
1023
+
1024
+ const expression: P<Ast.Expression> = Parser.suspend(() => expressionDef);
1025
+ const groupGraphPattern: P<Ast.GroupPattern> = Parser.suspend(() => groupGraphPatternDef);
1026
+
1027
+ const AGGREGATES: ReadonlyArray<Ast.AggregateName> = [
1028
+ 'COUNT',
1029
+ 'SUM',
1030
+ 'MIN',
1031
+ 'MAX',
1032
+ 'AVG',
1033
+ 'SAMPLE',
1034
+ 'GROUP_CONCAT',
1035
+ ];
1036
+ const AGGREGATE_KINDS = kindSet(AGGREGATES);
1037
+
1038
+ const isBuiltInStart = (t: Tok): boolean =>
1039
+ t.type === 'WORD' &&
1040
+ (Ast.isBuiltInName(t.kind) ||
1041
+ AGGREGATE_KINDS.has(t.kind) ||
1042
+ t.kind === 'EXISTS' ||
1043
+ t.kind === 'NOT');
1044
+
1045
+ const startsBuiltIn: P<unknown> = Parser.peek(
1046
+ take('a function', (t) => (isBuiltInStart(t) ? taken : notTaken)),
1047
+ );
1048
+
1049
+ const brackettedExpression: P<Ast.Expression> = Parser.delimited(
1050
+ expect('('),
1051
+ expression,
1052
+ expect(')'),
1053
+ );
1054
+
1055
+ const expressionList: P<Array<Ast.Expression>> = Parser.preceded(
1056
+ expect('('),
1057
+ Parser.alt(
1058
+ tok(')').pipe(Parser.as([])),
1059
+ Parser.terminated(Parser.separated(expression, tok(','), { min: 1 }), expect(')')),
1060
+ ),
1061
+ );
1062
+
1063
+ /** The arguments of a function call, and whether they are DISTINCT. */
1064
+ const functionArgs: P<readonly [ReadonlyArray<Ast.Expression>, boolean]> = Parser.alt(
1065
+ Parser.preceded(Parser.seq(nil, anyToken, anyToken), Parser.succeed([[], false] as const)),
1066
+ Parser.preceded(
1067
+ expect('('),
1068
+ Parser.seq(
1069
+ Parser.opt(
1070
+ take('DISTINCT', (t) => {
1071
+ if (t.kind !== 'DISTINCT') return notTaken;
1072
+ if (!ctx.aggregatesAllowed || ctx.inAggregate) {
1073
+ fail('DISTINCT is only allowed in aggregate function calls', t.start);
1074
+ }
1075
+ return taken;
1076
+ }),
1077
+ ),
1078
+ Parser.separated(expression, tok(','), { min: 1 }),
1079
+ expect(')'),
1080
+ ),
1081
+ ).pipe(Parser.map(([distinct, args]) => [args, Option.isSome(distinct)] as const)),
1082
+ );
1083
+
1084
+ const groupGraphPatternInExpression: P<Ast.GroupPattern> = withFlags(
1085
+ false,
1086
+ Option.some(false),
1087
+ groupGraphPattern,
1088
+ );
1089
+
1090
+ /** An aggregate, from its name. */
1091
+ const aggregate = (name: Ast.AggregateName): P<Ast.Expression> =>
1092
+ Parser.preceded(
1093
+ hook((t) => {
1094
+ if (!ctx.aggregatesAllowed) fail(`Aggregate ${name} is not allowed here`, offsetOf(t));
1095
+ if (ctx.inAggregate) fail('Aggregates cannot be nested', offsetOf(t));
1096
+ }),
1097
+ Parser.seq(
1098
+ Parser.preceded(Parser.seq(anyToken, expect('(')), eat('DISTINCT')),
1099
+ Parser.preceded(
1100
+ hook(() => {
1101
+ ctx.inAggregate = true;
1102
+ }),
1103
+ Parser.alt(
1104
+ ...(name === 'COUNT'
1105
+ ? [Parser.preceded(tok('*'), expect(')')).pipe(Parser.as<'*'>('*'))]
1106
+ : []),
1107
+ Parser.seq(
1108
+ expression,
1109
+ name === 'GROUP_CONCAT'
1110
+ ? Parser.opt(
1111
+ Parser.preceded(
1112
+ Parser.seq(tok(';'), expect('SEPARATOR'), expect('=')),
1113
+ Parser.alt(string, unexpectedHere<Tok>('a string')),
1114
+ ),
1115
+ )
1116
+ : Parser.succeed(Option.none<Tok>()),
1117
+ expect(')'),
1118
+ ),
1119
+ ),
1120
+ ),
1121
+ hook(() => {
1122
+ ctx.inAggregate = false;
1123
+ }),
1124
+ ),
1125
+ ).pipe(
1126
+ Parser.map(([distinct, body]) => {
1127
+ if (body === '*') return Ast.aggregate('COUNT', '*', { distinct });
1128
+ const [e, sep] = body;
1129
+ return Option.isSome(sep)
1130
+ ? Ast.aggregate(name, e, { distinct, separator: sep.value.value })
1131
+ : Ast.aggregate(name, e, { distinct });
1132
+ }),
1133
+ );
1134
+
1135
+ const BUILT_INS = Record.keys(Ast.builtInArity);
1136
+
1137
+ /** The built-in a token names (`peekKind(BUILT_INS)` lets only those through). */
1138
+ const builtInName = (t: Tok): Ast.BuiltInName =>
1139
+ Ast.isBuiltInName(t.kind) ? t.kind : unexpected(t, 'a function');
1140
+
1141
+ const builtInCall: P<Ast.Expression> = Parser.alt(
1142
+ // Built-ins with arguments: the arity is checked against the name.
1143
+ Parser.preceded(
1144
+ peekKind(BUILT_INS.filter((n) => n !== 'BOUND' && Ast.builtInArity[n][1] > 0)),
1145
+ Parser.seq(anyToken, expressionList),
1146
+ ).pipe(
1147
+ Parser.map(([t, args]) => {
1148
+ const name = builtInName(t);
1149
+ const [min, max] = Ast.builtInArity[name];
1150
+ return args.length < min || args.length > max
1151
+ ? fail(`${name} expects ${min === max ? min : `${min} to ${max}`} arguments`, t.start)
1152
+ : Ast.operation(name, ...args);
1153
+ }),
1154
+ ),
1155
+ Parser.preceded(
1156
+ peekKind(BUILT_INS.filter((n) => Ast.builtInArity[n][1] === 0)),
1157
+ Parser.seq(
1158
+ anyToken,
1159
+ Parser.alt(Parser.seq(nil, anyToken, anyToken), unexpectedHere<void>("'()'")),
1160
+ ),
1161
+ ).pipe(Parser.map(([t]) => Ast.operation(builtInName(t)))),
1162
+ Parser.preceded(
1163
+ Parser.seq(tok('BOUND'), expect('(')),
1164
+ Parser.terminated(variableOrError, expect(')')),
1165
+ ).pipe(Parser.map((v) => Ast.operation('BOUND', v))),
1166
+ Parser.preceded(tok('EXISTS'), groupGraphPatternInExpression).pipe(
1167
+ Parser.map((g) => Ast.exists(g, false)),
1168
+ ),
1169
+ Parser.preceded(Parser.seq(tok('NOT'), expect('EXISTS')), groupGraphPatternInExpression).pipe(
1170
+ Parser.map((g) => Ast.exists(g, true)),
1171
+ ),
1172
+ ...AGGREGATES.map((name) => Parser.preceded(peekKind([name]), aggregate(name))),
1173
+ );
1174
+
1175
+ const exprTripleTerm: P<Ast.Expression> = Parser.preceded(
1176
+ tok('<<('),
1177
+ Parser.seq(
1178
+ Parser.alt(variable, iriOrError),
1179
+ Parser.alt(tok('a').pipe(Parser.as(rdfType)), variable, iriOrError),
1180
+ Parser.alt(
1181
+ Parser.suspend(() => exprTripleTerm),
1182
+ variable,
1183
+ dataTerm,
1184
+ ),
1185
+ expect(')>>'),
1186
+ ),
1187
+ ).pipe(Parser.map(([s, p, o]) => Term.triple<any, any, any>(s, p, o)));
1188
+
1189
+ const primary: P<Ast.Expression> = Parser.alt(
1190
+ variable,
1191
+ Parser.seq(iri, Parser.opt(Parser.preceded(Parser.peek(tok('(')), functionArgs))).pipe(
1192
+ Parser.map(([i, args]): Ast.Expression =>
1193
+ Option.isSome(args) ? Ast.functionCall(i, args.value[0], args.value[1]) : i,
1194
+ ),
1195
+ ),
1196
+ rdfLiteral,
1197
+ numericLiteral,
1198
+ booleanLiteral,
1199
+ Parser.preceded(startsBuiltIn, builtInCall),
1200
+ Parser.preceded(Parser.peek(tok('(')), brackettedExpression),
1201
+ exprTripleTerm,
1202
+ unexpectedHere<Ast.Expression>('an expression'),
1203
+ );
1204
+
1205
+ const unary: P<Ast.Expression> = Parser.alt(
1206
+ Parser.preceded(
1207
+ tok('!'),
1208
+ Parser.suspend(() => unary),
1209
+ ).pipe(Parser.map((e) => Ast.operation('!', e))),
1210
+ signedNumber,
1211
+ Parser.seq(Parser.alt(tok('+'), tok('-')), primary).pipe(
1212
+ Parser.map(([op, e]) => Ast.operation(op.kind === '+' ? 'UPLUS' : 'UMINUS', e)),
1213
+ ),
1214
+ primary,
1215
+ );
1216
+
1217
+ /** Matches the token of an operator, typed as that operator. */
1218
+ const operator = <O extends Ast.Operator>(o: O): P<O> => tok(o).pipe(Parser.map(() => o));
1219
+
1220
+ const leftAssoc = (
1221
+ operand: P<Ast.Expression>,
1222
+ ops: ReadonlyArray<Ast.Operator>,
1223
+ ): P<Ast.Expression> =>
1224
+ Parser.seq(operand, Parser.repeat(Parser.seq(Parser.alt(...ops.map(operator)), operand))).pipe(
1225
+ Parser.map(([first, rest]) =>
1226
+ rest.reduce((left, [op, right]) => Ast.operation(op, left, right), first),
1227
+ ),
1228
+ );
1229
+
1230
+ const multiplicative = leftAssoc(unary, ['*', '/']);
1231
+ const additive = leftAssoc(multiplicative, ['+', '-']);
1232
+
1233
+ const relational: P<Ast.Expression> = Parser.seq(
1234
+ additive,
1235
+ Parser.opt(
1236
+ Parser.alt(
1237
+ Parser.seq(
1238
+ Parser.alt(...(['=', '!=', '<', '>', '<=', '>='] as const).map(operator)),
1239
+ additive,
1240
+ ).pipe(
1241
+ Parser.map(
1242
+ ([op, right]) =>
1243
+ (left: Ast.Expression) =>
1244
+ Ast.operation(op, left, right),
1245
+ ),
1246
+ ),
1247
+ Parser.preceded(tok('IN'), expressionList).pipe(
1248
+ Parser.map((list) => (left: Ast.Expression) => Ast.operation('IN', left, ...list)),
1249
+ ),
1250
+ Parser.preceded(Parser.seq(tok('NOT'), tok('IN')), expressionList).pipe(
1251
+ Parser.map((list) => (left: Ast.Expression) => Ast.operation('NOT IN', left, ...list)),
1252
+ ),
1253
+ ),
1254
+ ),
1255
+ ).pipe(Parser.map(([left, rest]) => (Option.isSome(rest) ? rest.value(left) : left)));
1256
+
1257
+ const conditionalAnd = leftAssoc(relational, ['&&']);
1258
+ const expressionDef = leftAssoc(conditionalAnd, ['||']);
1259
+
1260
+ const constraint: P<Ast.Expression> = Parser.alt(
1261
+ Parser.preceded(Parser.peek(tok('(')), brackettedExpression),
1262
+ Parser.preceded(startsBuiltIn, builtInCall),
1263
+ Parser.seq(
1264
+ iri,
1265
+ Parser.alt(
1266
+ Parser.preceded(Parser.peek(tok('(')), functionArgs),
1267
+ unexpectedHere<readonly [ReadonlyArray<Ast.Expression>, boolean]>("'('"),
1268
+ ),
1269
+ ).pipe(Parser.map(([i, [args, distinct]]) => Ast.functionCall(i, args, distinct))),
1270
+ unexpectedHere<Ast.Expression>('a constraint'),
1271
+ );
1272
+
1273
+ /** Whether a constraint (`(`, a built-in, an IRI) starts here. */
1274
+ const startsConstraint: P<unknown> = Parser.peek(
1275
+ take('a constraint', (t) => (t.kind === '(' || isBuiltInStart(t) || isIri(t) ? taken : notTaken)),
1276
+ );
1277
+
1278
+ // -----------------------------------------------------------------------------
1279
+ // Graph patterns
1280
+ // -----------------------------------------------------------------------------
1281
+
1282
+ const patternTriples = triplesGrammar(true);
1283
+ const templateTriples = triplesGrammar(false);
1284
+
1285
+ const varOrIri: P<Ast.VarOrIri> = Parser.alt(variable, iriOrError);
1286
+
1287
+ const GPNT = kindSet(['OPTIONAL', 'MINUS', 'GRAPH', 'SERVICE', 'FILTER', 'BIND', 'VALUES']);
1288
+
1289
+ const graphPatternNotTriples: P<Ast.Pattern> = select<Ast.Pattern>([
1290
+ [
1291
+ ['{'],
1292
+ Parser.seq(
1293
+ groupGraphPattern,
1294
+ Parser.repeat(Parser.preceded(tok('UNION'), groupGraphPattern)),
1295
+ ).pipe(
1296
+ Parser.map(([first, rest]) =>
1297
+ Arr.isReadonlyArrayEmpty(rest) ? first : Ast.union([first, ...rest]),
1298
+ ),
1299
+ ),
1300
+ ],
1301
+ [
1302
+ ['OPTIONAL'],
1303
+ Parser.preceded(anyToken, groupGraphPattern).pipe(Parser.map((g) => Ast.optional(g))),
1304
+ ],
1305
+ [['MINUS'], Parser.preceded(anyToken, groupGraphPattern).pipe(Parser.map((g) => Ast.minus(g)))],
1306
+ [
1307
+ ['GRAPH'],
1308
+ Parser.preceded(anyToken, Parser.seq(varOrIri, groupGraphPattern)).pipe(
1309
+ Parser.map(([name, g]) => Ast.graph(name, g)),
1310
+ ),
1311
+ ],
1312
+ [
1313
+ ['SERVICE'],
1314
+ Parser.preceded(anyToken, Parser.seq(eat('SILENT'), varOrIri, groupGraphPattern)).pipe(
1315
+ Parser.map(([silent, name, g]) => Ast.service(name, g, silent)),
1316
+ ),
1317
+ ],
1318
+ [['FILTER'], Parser.preceded(anyToken, constraint).pipe(Parser.map((e) => Ast.filter(e)))],
1319
+ [
1320
+ ['BIND'],
1321
+ Parser.preceded(
1322
+ Parser.seq(anyToken, expect('(')),
1323
+ Parser.seq(expression, Parser.preceded(expect('AS'), variableOrError), expect(')')),
1324
+ ).pipe(Parser.map(([e, v]) => Ast.bind(e, v))),
1325
+ ],
1326
+ [['VALUES'], Parser.preceded(anyToken, dataBlock)],
1327
+ ]);
1328
+
1329
+ const startsGPNT: P<unknown> = Parser.peek(
1330
+ take('a graph pattern', (t) =>
1331
+ t.kind === '{' || (t.type === 'WORD' && GPNT.has(t.kind)) ? taken : notTaken,
1332
+ ),
1333
+ );
1334
+
1335
+ type GroupItem =
1336
+ | { readonly _tag: 'Pattern'; readonly pattern: Ast.Pattern; readonly at: number }
1337
+ | { readonly _tag: 'Triples'; readonly triples: Triples };
1338
+
1339
+ const gpntItem: P<GroupItem> = Parser.preceded(
1340
+ startsGPNT,
1341
+ Parser.seq(
1342
+ hook((t) => offsetOf(t)),
1343
+ graphPatternNotTriples,
1344
+ eat('.'),
1345
+ ),
1346
+ ).pipe(
1347
+ Parser.map(([at, pattern]): GroupItem => {
1348
+ // After anything but a FILTER, the following triples are in a new BGP scope.
1349
+ if (!Predicate.isTagged(pattern, 'Filter')) {
1350
+ ctx.triples[ctx.triples.length - 1] = ctx.patternContext();
1351
+ }
1352
+ return { _tag: 'Pattern', pattern, at };
1353
+ }),
1354
+ );
1355
+
1356
+ const isGPNTStart = (t: Tok): boolean =>
1357
+ t.type !== 'ERROR' && (t.kind === '{' || (t.type === 'WORD' && GPNT.has(t.kind)));
1358
+
1359
+ /** A triples block; one not ended by `.` must be followed by a pattern or `}`. */
1360
+ const triplesItem: P<GroupItem> = Parser.preceded(
1361
+ startsTriples,
1362
+ Parser.seq(
1363
+ patternTriples.triplesBlock,
1364
+ hook((t) => t),
1365
+ ),
1366
+ ).pipe(
1367
+ Parser.map(([[triples, dot], t]): GroupItem => {
1368
+ if (!dot && t.kind !== '}' && !isGPNTStart(t)) unexpectedAt(t, "'.' or '}'");
1369
+ return { _tag: 'Triples', triples };
1370
+ }),
1371
+ );
1372
+
1373
+ /** The elements of a group, up to its `}` (not consumed). */
1374
+ const groupItems: P<Array<GroupItem>> = Parser.repeat(
1375
+ Parser.preceded(
1376
+ Parser.not(tok('}')),
1377
+ Parser.alt(gpntItem, triplesItem, unexpectedHere<GroupItem>()),
1378
+ ),
1379
+ );
1380
+
1381
+ /**
1382
+ * Adds a group item to the patterns read so far; the failure if it is a
1383
+ * `BIND` of a variable already in scope.
1384
+ */
1385
+ const addGroupItem = (patterns: Array<Ast.Pattern>, item: GroupItem): Option.Option<Failure> => {
1386
+ if (Predicate.isTagged(item, 'Triples')) {
1387
+ const last = patterns[patterns.length - 1];
1388
+ if (Predicate.isTagged(last, 'Bgp')) {
1389
+ patterns[patterns.length - 1] = Ast.bgp([...last.triples, ...item.triples]);
1390
+ } else patterns.push(Ast.bgp(item.triples));
1391
+ return Option.none();
1392
+ }
1393
+ const p = item.pattern;
1394
+ if (Predicate.isTagged(p, 'Bind')) {
1395
+ const name = p.variable.value;
1396
+ if (patterns.some((q) => Ast.inScopeVariables(q).includes(name))) {
1397
+ return Option.some(new Failure(`BIND variable ?${name} is already in scope`, item.at));
1398
+ }
1399
+ }
1400
+ patterns.push(p);
1401
+ return Option.none();
1402
+ };
1403
+
1404
+ const assembleGroup = (
1405
+ items: ReadonlyArray<GroupItem>,
1406
+ ): Result.Result<Ast.GroupPattern, Failure> => {
1407
+ const patterns: Array<Ast.Pattern> = [];
1408
+ return Option.match(
1409
+ Arr.findFirst(items, (item) => addGroupItem(patterns, item)),
1410
+ { onNone: () => Result.succeed(Ast.group(patterns)), onSome: Result.fail },
1411
+ );
1412
+ };
1413
+
1414
+ const subSelect: P<Ast.GroupPattern> = Parser.suspend(() => subSelectDef);
1415
+
1416
+ const groupGraphPatternDef: P<Ast.GroupPattern> = Parser.preceded(
1417
+ expect('{'),
1418
+ Parser.alt(
1419
+ Parser.preceded(Parser.peek(tok('SELECT')), subSelect),
1420
+ inContext(() => ctx.patternContext(), Parser.terminated(groupItems, expect('}'))).pipe(
1421
+ Parser.tryMap(assembleGroup),
1422
+ Parser.cut,
1423
+ ),
1424
+ ),
1425
+ );
1426
+
1427
+ // -----------------------------------------------------------------------------
1428
+ // Queries
1429
+ // -----------------------------------------------------------------------------
1430
+
1431
+ interface Prologue {
1432
+ readonly value: () => Ast.Prologue;
1433
+ }
1434
+
1435
+ let prologue: Prologue = { value: () => ({ prefixes: {} }) };
1436
+
1437
+ /** Skips the prologue (names are resolved by the lexer), recording `VERSION`. */
1438
+ const prologueDecls: P<void> = Parser.asVoid(
1439
+ Parser.repeat(
1440
+ select<unknown>([
1441
+ [
1442
+ ['BASE'],
1443
+ Parser.preceded(
1444
+ anyToken,
1445
+ Parser.alt(
1446
+ take('an IRI', (t) => (t.type === 'IRI' ? Option.some(t) : notTaken)),
1447
+ unexpectedHere('an IRI'),
1448
+ ),
1449
+ ),
1450
+ ],
1451
+ [
1452
+ ['PREFIX'],
1453
+ Parser.preceded(
1454
+ anyToken,
1455
+ Parser.seq(
1456
+ Parser.alt(
1457
+ take('a prefix name', (t) =>
1458
+ t.type === 'PNAME' && t.value === '' ? Option.some(t) : notTaken,
1459
+ ),
1460
+ unexpectedHere('a prefix name'),
1461
+ ),
1462
+ Parser.alt(
1463
+ take('an IRI', (t) => (t.type === 'IRI' ? Option.some(t) : notTaken)),
1464
+ unexpectedHere('an IRI'),
1465
+ ),
1466
+ ),
1467
+ ),
1468
+ ],
1469
+ [
1470
+ ['VERSION'],
1471
+ Parser.preceded(
1472
+ anyToken,
1473
+ Parser.alt(
1474
+ take('a version string', (t) => {
1475
+ if (t.type !== 'STRING' || t.extra === 'long') return notTaken;
1476
+ ctx.version = Option.some(t.value);
1477
+ return Option.some(t);
1478
+ }),
1479
+ unexpectedHere('a version string'),
1480
+ ),
1481
+ ),
1482
+ ],
1483
+ ]),
1484
+ ),
1485
+ );
1486
+
1487
+ type Modifiers = Pick<Ast.QueryBase, 'groupBy' | 'having' | 'orderBy' | 'limit' | 'offset'>;
1488
+
1489
+ /** `query` with its dataset clause; an absent clause leaves the member absent. */
1490
+ const withDataset = <Q extends Ast.QueryBase>(
1491
+ query: Q,
1492
+ dataset: Option.Option<Ast.DatasetClause>,
1493
+ ): Q => (Option.isNone(dataset) ? query : { ...query, dataset: dataset.value });
1494
+
1495
+ const withAggregates = <A>(p: P<A>): P<A> => withFlags(true, Option.none(), p);
1496
+
1497
+ const groupCondition: P<Ast.GroupCondition> = Parser.alt(
1498
+ variable.pipe(Parser.map((v): Ast.GroupCondition => ({ expression: v }))),
1499
+ Parser.preceded(
1500
+ tok('('),
1501
+ Parser.seq(expression, Parser.opt(Parser.preceded(tok('AS'), variableOrError)), expect(')')),
1502
+ ).pipe(
1503
+ Parser.map(([e, v]): Ast.GroupCondition =>
1504
+ Option.isSome(v) ? { expression: e, variable: v.value } : { expression: e },
1505
+ ),
1506
+ ),
1507
+ Parser.preceded(
1508
+ Parser.peek(take('a constraint', (t) => (isBuiltInStart(t) || isIri(t) ? taken : notTaken))),
1509
+ constraint,
1510
+ ).pipe(Parser.map((e): Ast.GroupCondition => ({ expression: e }))),
1511
+ );
1512
+
1513
+ const orderCondition: P<Ast.OrderCondition> = Parser.alt(
1514
+ Parser.seq(
1515
+ Parser.alt(tok('ASC'), tok('DESC')),
1516
+ Parser.alt(
1517
+ Parser.preceded(Parser.peek(tok('(')), brackettedExpression),
1518
+ unexpectedHere<Ast.Expression>("'('"),
1519
+ ),
1520
+ ).pipe(
1521
+ Parser.map(([d, e]): Ast.OrderCondition => ({
1522
+ expression: e,
1523
+ descending: d.kind === 'DESC',
1524
+ })),
1525
+ ),
1526
+ variable.pipe(Parser.map((v): Ast.OrderCondition => ({ expression: v, descending: false }))),
1527
+ Parser.preceded(startsConstraint, constraint).pipe(
1528
+ Parser.map((e): Ast.OrderCondition => ({ expression: e, descending: false })),
1529
+ ),
1530
+ );
1531
+
1532
+ const atLeastOne = <A>(p: P<A>, label: string): P<Array<A>> =>
1533
+ Parser.seq(
1534
+ Parser.repeat(p),
1535
+ hook((t) => t),
1536
+ ).pipe(
1537
+ Parser.tryMap(([items, t]) =>
1538
+ Arr.isReadonlyArrayEmpty(items)
1539
+ ? Result.fail(
1540
+ new Failure(
1541
+ t.type === 'ERROR' ? t.value : `Unexpected ${describe(t)}, expected ${label}`,
1542
+ offsetOf(t),
1543
+ ),
1544
+ )
1545
+ : Result.succeed(items),
1546
+ ),
1547
+ Parser.cut,
1548
+ );
1549
+
1550
+ const integer: P<number> = Parser.alt(
1551
+ take('an integer', (t) => (t.type === 'INTEGER' ? Option.some(Number(t.value)) : notTaken)),
1552
+ unexpectedHere<number>('an integer'),
1553
+ );
1554
+
1555
+ const solutionModifiers: P<Modifiers> = Parser.seq(
1556
+ Parser.opt(
1557
+ Parser.preceded(
1558
+ Parser.seq(tok('GROUP'), expect('BY')),
1559
+ atLeastOne(groupCondition, 'a grouping condition'),
1560
+ ),
1561
+ ),
1562
+ Parser.opt(
1563
+ Parser.preceded(
1564
+ tok('HAVING'),
1565
+ Parser.seq(
1566
+ withAggregates(Parser.repeat(Parser.preceded(startsConstraint, constraint))),
1567
+ hook((t) => t),
1568
+ ),
1569
+ ).pipe(
1570
+ Parser.map(([having, t]) =>
1571
+ Arr.isReadonlyArrayNonEmpty(having) ? having : unexpectedAt(t, 'a HAVING condition'),
1572
+ ),
1573
+ ),
1574
+ ),
1575
+ Parser.opt(
1576
+ Parser.preceded(
1577
+ Parser.seq(tok('ORDER'), expect('BY')),
1578
+ Parser.seq(
1579
+ withAggregates(Parser.repeat(orderCondition)),
1580
+ hook((t) => t),
1581
+ ),
1582
+ ).pipe(
1583
+ Parser.map(([orderBy, t]) =>
1584
+ Arr.isReadonlyArrayNonEmpty(orderBy) ? orderBy : unexpectedAt(t, 'an ORDER BY condition'),
1585
+ ),
1586
+ ),
1587
+ ),
1588
+ Parser.alt(
1589
+ Parser.seq(
1590
+ Parser.preceded(tok('LIMIT'), integer).pipe(Parser.map(Option.some)),
1591
+ Parser.opt(Parser.preceded(tok('OFFSET'), integer)),
1592
+ ),
1593
+ Parser.seq(
1594
+ Parser.preceded(tok('OFFSET'), integer).pipe(Parser.map(Option.some)),
1595
+ Parser.opt(Parser.preceded(tok('LIMIT'), integer)),
1596
+ ).pipe(Parser.map(([offset, limit]) => [limit, offset] as const)),
1597
+ Parser.succeed([Option.none<number>(), Option.none<number>()] as const),
1598
+ ),
1599
+ ).pipe(
1600
+ Parser.map(([groupBy, having, orderBy, [limit, offset]]): Modifiers => {
1601
+ const modifiers: Modifiers = {
1602
+ groupBy: Option.getOrElse(groupBy, () => []),
1603
+ having: Option.getOrElse(having, () => []),
1604
+ orderBy: Option.getOrElse(orderBy, () => []),
1605
+ };
1606
+ const limited = Option.isNone(limit) ? modifiers : { ...modifiers, limit: limit.value };
1607
+ return Option.isNone(offset) ? limited : { ...limited, offset: offset.value };
1608
+ }),
1609
+ );
1610
+
1611
+ const datasetClauses: P<Option.Option<Ast.DatasetClause>> = Parser.repeat(
1612
+ Parser.preceded(tok('FROM'), Parser.seq(eat('NAMED'), iriOrError)),
1613
+ ).pipe(
1614
+ Parser.map((clauses) =>
1615
+ Arr.isReadonlyArrayEmpty(clauses)
1616
+ ? Option.none()
1617
+ : Option.some({
1618
+ default: clauses.filter(([named]) => !named).map(([, i]) => i),
1619
+ named: clauses.filter(([named]) => named).map(([, i]) => i),
1620
+ }),
1621
+ ),
1622
+ );
1623
+
1624
+ const valuesClause: P<Option.Option<Ast.ValuesPattern>> = Parser.opt(
1625
+ Parser.preceded(tok('VALUES'), dataBlock),
1626
+ );
1627
+
1628
+ const projectionItem: P<Term.Variable | Ast.Projection> = Parser.alt(
1629
+ variable,
1630
+ Parser.preceded(
1631
+ tok('('),
1632
+ Parser.seq(
1633
+ withAggregates(expression),
1634
+ Parser.preceded(expect('AS'), variableOrError),
1635
+ expect(')'),
1636
+ ),
1637
+ ).pipe(
1638
+ Parser.map(([e, v]): Ast.Projection => ({
1639
+ _tag: 'Projection',
1640
+ expression: e,
1641
+ variable: v,
1642
+ })),
1643
+ ),
1644
+ );
1645
+
1646
+ const selectQuery = (sub: boolean): P<Ast.SelectQuery> =>
1647
+ Parser.preceded(
1648
+ expect('SELECT'),
1649
+ Parser.seq(
1650
+ Parser.alt(
1651
+ tok('DISTINCT').pipe(Parser.as([true, false] as const)),
1652
+ tok('REDUCED').pipe(Parser.as([false, true] as const)),
1653
+ Parser.succeed([false, false] as const),
1654
+ ),
1655
+ Parser.alt(
1656
+ tok('*').pipe(Parser.as<'*'>('*')),
1657
+ atLeastOne(projectionItem, 'a variable, expression or *'),
1658
+ ),
1659
+ sub ? Parser.succeed(Option.none<Ast.DatasetClause>()) : datasetClauses,
1660
+ Parser.preceded(eat('WHERE'), groupGraphPattern),
1661
+ solutionModifiers,
1662
+ ),
1663
+ ).pipe(
1664
+ Parser.map(([[distinct, reduced], projection, dataset, where, modifiers]): Ast.SelectQuery =>
1665
+ withDataset(
1666
+ {
1667
+ _tag: 'Select',
1668
+ prologue: prologue.value(),
1669
+ distinct,
1670
+ reduced,
1671
+ projection,
1672
+ where,
1673
+ ...modifiers,
1674
+ },
1675
+ dataset,
1676
+ ),
1677
+ ),
1678
+ );
1679
+
1680
+ // `templateTriples` parses no property paths, so a template's items are all triple patterns.
1681
+ const constructTemplate: P<Array<Ast.TriplePattern>> = Parser.delimited(
1682
+ tok('{'),
1683
+ Parser.cut(
1684
+ inContext(
1685
+ () => ({
1686
+ variables: true,
1687
+ blankNodes: true,
1688
+ scope: ++ctx.scopeCounter,
1689
+ labels: ctx.templateLabels,
1690
+ }),
1691
+ templateTriples.triplesTemplate,
1692
+ ),
1693
+ ),
1694
+ expect('}'),
1695
+ ).pipe(Parser.map((t) => t.filter(isTriplePattern)));
1696
+
1697
+ const constructQuery: P<Ast.ConstructQuery> = Parser.preceded(
1698
+ tok('CONSTRUCT'),
1699
+ Parser.alt(
1700
+ Parser.seq(
1701
+ constructTemplate,
1702
+ datasetClauses,
1703
+ Parser.preceded(eat('WHERE'), groupGraphPattern),
1704
+ solutionModifiers,
1705
+ ).pipe(
1706
+ Parser.map(([template, dataset, where, modifiers]): Ast.ConstructQuery =>
1707
+ withDataset(
1708
+ { _tag: 'Construct', prologue: prologue.value(), template, where, ...modifiers },
1709
+ dataset,
1710
+ ),
1711
+ ),
1712
+ ),
1713
+ Parser.seq(
1714
+ datasetClauses,
1715
+ Parser.delimited(
1716
+ Parser.seq(expect('WHERE'), expect('{')),
1717
+ inContext(() => ctx.patternContext(), templateTriples.triplesTemplate),
1718
+ expect('}'),
1719
+ ),
1720
+ solutionModifiers,
1721
+ ).pipe(
1722
+ Parser.map(([dataset, triples, modifiers]): Ast.ConstructQuery => {
1723
+ // `templateTriples` parses no property paths, so the short-form template's items are all
1724
+ // triple patterns.
1725
+ const template = triples.filter(isTriplePattern);
1726
+ return withDataset(
1727
+ {
1728
+ _tag: 'Construct',
1729
+ prologue: prologue.value(),
1730
+ template,
1731
+ where: Ast.group(Arr.isReadonlyArrayNonEmpty(template) ? [Ast.bgp(template)] : []),
1732
+ short: true,
1733
+ ...modifiers,
1734
+ },
1735
+ dataset,
1736
+ );
1737
+ }),
1738
+ ),
1739
+ ),
1740
+ );
1741
+
1742
+ const describeQuery: P<Ast.DescribeQuery> = Parser.preceded(
1743
+ tok('DESCRIBE'),
1744
+ Parser.seq(
1745
+ Parser.alt(
1746
+ tok('*').pipe(Parser.as<'*'>('*')),
1747
+ atLeastOne(Parser.alt(variable, iri), 'a variable, IRI or *'),
1748
+ ),
1749
+ datasetClauses,
1750
+ Parser.alt(
1751
+ Parser.preceded(
1752
+ Parser.peek(Parser.alt(tok('WHERE'), tok('{'))),
1753
+ Parser.preceded(eat('WHERE'), groupGraphPattern),
1754
+ ),
1755
+ Parser.succeed(Ast.group([])),
1756
+ ),
1757
+ solutionModifiers,
1758
+ ),
1759
+ ).pipe(
1760
+ Parser.map(([terms, dataset, where, modifiers]): Ast.DescribeQuery =>
1761
+ withDataset(
1762
+ { _tag: 'Describe', prologue: prologue.value(), terms, where, ...modifiers },
1763
+ dataset,
1764
+ ),
1765
+ ),
1766
+ );
1767
+
1768
+ const askQuery: P<Ast.AskQuery> = Parser.preceded(
1769
+ tok('ASK'),
1770
+ Parser.seq(datasetClauses, Parser.preceded(eat('WHERE'), groupGraphPattern), solutionModifiers),
1771
+ ).pipe(
1772
+ Parser.map(([dataset, where, modifiers]): Ast.AskQuery =>
1773
+ withDataset({ _tag: 'Ask', prologue: prologue.value(), where, ...modifiers }, dataset),
1774
+ ),
1775
+ );
1776
+
1777
+ const subSelectDef: P<Ast.GroupPattern> = Parser.seq(
1778
+ withFlags(false, Option.none(), Parser.seq(selectQuery(true), valuesClause)),
1779
+ Parser.preceded(
1780
+ expect('}'),
1781
+ hook((t) => offsetOf(t)),
1782
+ ),
1783
+ ).pipe(
1784
+ Parser.map(([[query, values], at]) => {
1785
+ const sub = Option.isSome(values) ? { ...query, values: values.value } : query;
1786
+ validateSelect(sub, at);
1787
+ return Ast.group([Ast.subSelect(sub)]);
1788
+ }),
1789
+ );
1790
+
1791
+ // -----------------------------------------------------------------------------
1792
+ // Static checks
1793
+ // -----------------------------------------------------------------------------
1794
+
1795
+ /** The variable a `GROUP BY` condition binds: its `AS` variable, or the variable it is. */
1796
+ const groupKey = (g: Ast.GroupCondition): Option.Option<string> =>
1797
+ g.variable !== undefined
1798
+ ? Option.some(g.variable.value)
1799
+ : Term.isVariable(g.expression)
1800
+ ? Option.some(g.expression.value)
1801
+ : Option.none();
1802
+
1803
+ const validateSelect = (query: Ast.SelectQuery, offset: number): void => {
1804
+ // Variables introduced by AS must not already be in scope.
1805
+ const projection = query.projection;
1806
+ if (projection !== '*') {
1807
+ const grouped =
1808
+ Arr.isReadonlyArrayNonEmpty(query.groupBy) ||
1809
+ projection.some((p) => !Term.isVariable(p) && Ast.containsAggregate(p.expression));
1810
+ // With grouping only the group keys are in scope; otherwise the
1811
+ // pattern's variables are.
1812
+ const inScope = MutableHashSet.fromIterable(grouped ? [] : Ast.inScopeVariables(query.where));
1813
+ Arr.forEach(Arr.getSomes(query.groupBy.map(groupKey)), (v) => MutableHashSet.add(inScope, v));
1814
+ // Variables of a trailing VALUES clause are joined before projection.
1815
+ (query.values?.variables ?? []).forEach((v) => MutableHashSet.add(inScope, v.value));
1816
+ const seen = MutableHashSet.empty<string>();
1817
+ projection.forEach((item) => {
1818
+ if (Term.isVariable(item)) {
1819
+ MutableHashSet.add(seen, item.value);
1820
+ return;
1821
+ }
1822
+ const name = item.variable.value;
1823
+ if (MutableHashSet.has(inScope, name) || MutableHashSet.has(seen, name)) {
1824
+ fail(`Variable ?${name} is already in scope`, offset);
1825
+ }
1826
+ MutableHashSet.add(seen, name);
1827
+ });
1828
+ }
1829
+ validateGrouping(query, offset);
1830
+ };
1831
+
1832
+ const validateGrouping = (query: Ast.Query, offset: number): void => {
1833
+ const projectionExprs =
1834
+ Predicate.isTagged(query, 'Select') && query.projection !== '*'
1835
+ ? query.projection.flatMap((p) => (Term.isVariable(p) ? [] : [p.expression]))
1836
+ : [];
1837
+ const grouped =
1838
+ Arr.isReadonlyArrayNonEmpty(query.groupBy) ||
1839
+ projectionExprs.some(Ast.containsAggregate) ||
1840
+ query.having.some(Ast.containsAggregate) ||
1841
+ query.orderBy.some((o) => Ast.containsAggregate(o.expression));
1842
+ query.groupBy.forEach((g) => {
1843
+ if (Ast.containsAggregate(g.expression)) fail('Aggregates are not allowed in GROUP BY', offset);
1844
+ });
1845
+ if (!grouped || !Predicate.isTagged(query, 'Select')) return;
1846
+ const projection = query.projection;
1847
+ if (projection === '*') {
1848
+ return fail('SELECT * is not allowed with GROUP BY or aggregates', offset);
1849
+ }
1850
+ const allowed = MutableHashSet.fromIterable(query.values?.variables.map((v) => v.value) ?? []);
1851
+ Arr.forEach(Arr.getSomes(query.groupBy.map(groupKey)), (v) => MutableHashSet.add(allowed, v));
1852
+ const checkVariable = (v: string): void => {
1853
+ if (!MutableHashSet.has(allowed, v)) fail(`Variable ?${v} is not grouped`, offset);
1854
+ };
1855
+ const checkExpr = (e: Ast.Expression): void => {
1856
+ Match.value(e).pipe(
1857
+ Match.tag('Variable', (v) => checkVariable(v.value)),
1858
+ Match.tag('Operation', 'FunctionCall', (call) => call.args.forEach(checkExpr)),
1859
+ Match.tag('Triple', (x) => Ast.expressionVariables(x).forEach(checkVariable)),
1860
+ Match.orElse(() => undefined),
1861
+ );
1862
+ };
1863
+ projection.forEach((item) => {
1864
+ if (Term.isVariable(item)) checkVariable(item.value);
1865
+ else {
1866
+ checkExpr(item.expression);
1867
+ MutableHashSet.add(allowed, item.variable.value);
1868
+ }
1869
+ });
1870
+ };
1871
+
1872
+ const checked =
1873
+ <A>(f: (a: A) => void) =>
1874
+ (a: A): Result.Result<A, Failure> =>
1875
+ catchFailure(() => {
1876
+ f(a);
1877
+ return a;
1878
+ });
1879
+
1880
+ const queryUnit = Compiler.jit(
1881
+ Parser.preceded(
1882
+ Parser.seq(start, prologueDecls),
1883
+ Parser.seq(
1884
+ select<Ast.Query>(
1885
+ [
1886
+ [['SELECT'], selectQuery(false)],
1887
+ [['CONSTRUCT'], constructQuery],
1888
+ [['DESCRIBE'], describeQuery],
1889
+ [['ASK'], askQuery],
1890
+ ],
1891
+ unexpectedHere<Ast.Query>('SELECT, CONSTRUCT, DESCRIBE or ASK'),
1892
+ ),
1893
+ valuesClause,
1894
+ Parser.alt(Parser.eof, unexpectedHere<void>()),
1895
+ ).pipe(
1896
+ Parser.map(([query, values]): Ast.Query =>
1897
+ Option.isSome(values) ? { ...query, values: values.value } : query,
1898
+ ),
1899
+ Parser.tryMap(
1900
+ checked((query: Ast.Query) => {
1901
+ if (Predicate.isTagged(query, 'Select')) validateSelect(query, 0);
1902
+ else validateGrouping(query, 0);
1903
+ }),
1904
+ ),
1905
+ Parser.cut,
1906
+ ),
1907
+ ),
1908
+ );
1909
+
1910
+ // -----------------------------------------------------------------------------
1911
+ // Updates
1912
+ // -----------------------------------------------------------------------------
1913
+
1914
+ const quadPattern: P<Array<Ast.QuadPattern>> = Parser.delimited(
1915
+ expect('{'),
1916
+ Parser.repeat(
1917
+ Parser.preceded(
1918
+ Parser.not(tok('}')),
1919
+ Parser.alt(
1920
+ Parser.preceded(
1921
+ tok('GRAPH'),
1922
+ Parser.seq(
1923
+ Parser.preceded(
1924
+ hook((t) => {
1925
+ if (t.type === 'VAR' && !ctx.tc.variables)
1926
+ fail('Variables are not allowed here', t.start);
1927
+ }),
1928
+ varOrIri,
1929
+ ),
1930
+ Parser.delimited(expect('{'), templateTriples.triplesTemplate, expect('}')),
1931
+ eat('.'),
1932
+ ),
1933
+ ).pipe(
1934
+ // `templateTriples` parses no property paths, so every quad-data item is a triple
1935
+ // pattern.
1936
+ Parser.map(([g, triples]) =>
1937
+ triples
1938
+ .filter(isTriplePattern)
1939
+ .map((tp) => Ast.quadPattern(tp.subject, tp.predicate, tp.object, g)),
1940
+ ),
1941
+ ),
1942
+ Parser.terminated(
1943
+ Parser.preceded(
1944
+ Parser.alt(startsTriples, unexpectedHere<void>()),
1945
+ templateTriples.triplesTemplate,
1946
+ ),
1947
+ Parser.alt(
1948
+ Parser.peek(Parser.alt(tok('}'), tok('GRAPH'))),
1949
+ unexpectedHere<void>("'.' or '}'"),
1950
+ ),
1951
+ ).pipe(
1952
+ Parser.map((triples) =>
1953
+ triples
1954
+ .filter(isTriplePattern)
1955
+ .map((tp) => Ast.quadPattern(tp.subject, tp.predicate, tp.object, Term.defaultGraph)),
1956
+ ),
1957
+ ),
1958
+ ),
1959
+ ),
1960
+ ),
1961
+ expect('}'),
1962
+ ).pipe(Parser.map((lists) => lists.flat()));
1963
+
1964
+ const templateContext = (blankNodes: boolean) => (): TripleContext => ({
1965
+ variables: true,
1966
+ blankNodes,
1967
+ scope: ctx.opIndex,
1968
+ labels: StringMap.empty(),
1969
+ });
1970
+
1971
+ const quadData = (blankNodes: boolean): P<Array<Term.Quad>> =>
1972
+ inContext(
1973
+ () => ({ variables: false, blankNodes, scope: ctx.opIndex, labels: ctx.templateLabels }),
1974
+ quadPattern,
1975
+ ).pipe(
1976
+ Parser.map((quads) =>
1977
+ quads.map(
1978
+ (q) => new Term.Quad<any, any, any, any>(q.subject, q.predicate, q.object, q.graph),
1979
+ ),
1980
+ ),
1981
+ );
1982
+
1983
+ const usingClauses = Parser.repeat(
1984
+ Parser.preceded(tok('USING'), Parser.seq(eat('NAMED'), iriOrError)),
1985
+ );
1986
+
1987
+ const modify = (deleteFirst: boolean): P<Ast.ModifyOperation> =>
1988
+ Parser.seq(
1989
+ deleteFirst
1990
+ ? Parser.seq(
1991
+ inContext(templateContext(false), quadPattern),
1992
+ Parser.opt(Parser.preceded(tok('INSERT'), inContext(templateContext(true), quadPattern))),
1993
+ ).pipe(Parser.map(([del, ins]) => [del, Option.getOrElse(ins, () => [])] as const))
1994
+ : inContext(templateContext(true), quadPattern).pipe(Parser.map((ins) => [[], ins] as const)),
1995
+ usingClauses,
1996
+ Parser.preceded(expect('WHERE'), groupGraphPattern),
1997
+ ).pipe(
1998
+ Parser.map(([[del, ins], using, where]): Ast.ModifyOperation => {
1999
+ const op: Ast.ModifyOperation = { _tag: 'Modify', delete: del, insert: ins, where };
2000
+ return Arr.isReadonlyArrayEmpty(using)
2001
+ ? op
2002
+ : {
2003
+ ...op,
2004
+ using: {
2005
+ default: using.filter(([named]) => !named).map(([, i]) => i),
2006
+ named: using.filter(([named]) => named).map(([, i]) => i),
2007
+ },
2008
+ };
2009
+ }),
2010
+ );
2011
+
2012
+ const graphRefAll: P<Ast.GraphTarget> = Parser.alt(
2013
+ tok('DEFAULT').pipe(Parser.as<Ast.GraphTarget>({ _tag: 'Default' })),
2014
+ tok('NAMED').pipe(Parser.as<Ast.GraphTarget>({ _tag: 'Named' })),
2015
+ tok('ALL').pipe(Parser.as<Ast.GraphTarget>({ _tag: 'All' })),
2016
+ Parser.preceded(expect('GRAPH'), iriOrError),
2017
+ );
2018
+
2019
+ const graphOrDefault: P<Ast.GraphOrDefault> = Parser.alt(
2020
+ tok('DEFAULT').pipe(Parser.as<Ast.GraphOrDefault>(Term.defaultGraph)),
2021
+ Parser.preceded(eat('GRAPH'), iriOrError),
2022
+ );
2023
+
2024
+ const update1: P<Ast.UpdateOperation> = select<Ast.UpdateOperation>(
2025
+ [
2026
+ [
2027
+ ['LOAD'],
2028
+ Parser.preceded(
2029
+ anyToken,
2030
+ Parser.seq(
2031
+ eat('SILENT'),
2032
+ iriOrError,
2033
+ Parser.opt(Parser.preceded(Parser.seq(tok('INTO'), expect('GRAPH')), iriOrError)),
2034
+ ),
2035
+ ).pipe(
2036
+ Parser.map(([silent, source, dest]): Ast.UpdateOperation =>
2037
+ Option.isSome(dest)
2038
+ ? { _tag: 'Load', silent, source, destination: dest.value }
2039
+ : { _tag: 'Load', silent, source },
2040
+ ),
2041
+ ),
2042
+ ],
2043
+ [
2044
+ ['CLEAR', 'DROP'],
2045
+ Parser.seq(anyToken, eat('SILENT'), graphRefAll).pipe(
2046
+ Parser.map(([t, silent, target]): Ast.UpdateOperation => ({
2047
+ _tag: t.kind === 'CLEAR' ? 'Clear' : 'Drop',
2048
+ silent,
2049
+ target,
2050
+ })),
2051
+ ),
2052
+ ],
2053
+ [
2054
+ ['CREATE'],
2055
+ Parser.preceded(
2056
+ anyToken,
2057
+ Parser.seq(eat('SILENT'), Parser.preceded(expect('GRAPH'), iriOrError)),
2058
+ ).pipe(
2059
+ Parser.map(([silent, graph]): Ast.UpdateOperation => ({ _tag: 'Create', silent, graph })),
2060
+ ),
2061
+ ],
2062
+ [
2063
+ ['ADD', 'MOVE', 'COPY'],
2064
+ Parser.seq(
2065
+ anyToken,
2066
+ eat('SILENT'),
2067
+ graphOrDefault,
2068
+ Parser.preceded(expect('TO'), graphOrDefault),
2069
+ ).pipe(
2070
+ Parser.map(([t, silent, source, destination]): Ast.UpdateOperation => ({
2071
+ _tag: t.kind === 'ADD' ? 'Add' : t.kind === 'MOVE' ? 'Move' : 'Copy',
2072
+ silent,
2073
+ source,
2074
+ destination,
2075
+ })),
2076
+ ),
2077
+ ],
2078
+ [
2079
+ ['INSERT'],
2080
+ Parser.preceded(
2081
+ anyToken,
2082
+ Parser.alt(
2083
+ Parser.preceded(tok('DATA'), quadData(true)).pipe(
2084
+ Parser.map((quads): Ast.UpdateOperation => ({ _tag: 'InsertData', quads })),
2085
+ ),
2086
+ modify(false),
2087
+ ),
2088
+ ),
2089
+ ],
2090
+ [
2091
+ ['DELETE'],
2092
+ Parser.preceded(
2093
+ anyToken,
2094
+ Parser.alt(
2095
+ Parser.preceded(tok('DATA'), quadData(false)).pipe(
2096
+ Parser.map((quads): Ast.UpdateOperation => ({ _tag: 'DeleteData', quads })),
2097
+ ),
2098
+ Parser.preceded(
2099
+ tok('WHERE'),
2100
+ inContext(
2101
+ () => ({
2102
+ variables: true,
2103
+ blankNodes: false,
2104
+ scope: ++ctx.scopeCounter,
2105
+ labels: ctx.patternLabels,
2106
+ }),
2107
+ quadPattern,
2108
+ ),
2109
+ ).pipe(
2110
+ Parser.map((patterns): Ast.UpdateOperation => ({ _tag: 'DeleteWhere', patterns })),
2111
+ ),
2112
+ modify(true),
2113
+ ),
2114
+ ),
2115
+ ],
2116
+ [
2117
+ ['WITH'],
2118
+ Parser.seq(
2119
+ Parser.preceded(anyToken, iriOrError),
2120
+ Parser.alt(
2121
+ Parser.preceded(tok('DELETE'), modify(true)),
2122
+ Parser.preceded(expect('INSERT'), modify(false)),
2123
+ ),
2124
+ ).pipe(
2125
+ Parser.map(([i, { _tag, ...rest }]): Ast.UpdateOperation => ({ _tag, with: i, ...rest })),
2126
+ ),
2127
+ ],
2128
+ ],
2129
+ unexpectedHere<Ast.UpdateOperation>('an update operation'),
2130
+ );
2131
+
2132
+ const update1Indexed: P<Ast.UpdateOperation> = Parser.terminated(
2133
+ update1,
2134
+ hook(() => {
2135
+ ctx.opIndex++;
2136
+ }),
2137
+ );
2138
+
2139
+ const updateUnit = Compiler.jit(
2140
+ Parser.preceded(
2141
+ Parser.seq(start, prologueDecls),
2142
+ Parser.terminated(
2143
+ Parser.opt(
2144
+ Parser.preceded(
2145
+ Parser.not(Parser.eof),
2146
+ Parser.separated(
2147
+ update1Indexed,
2148
+ Parser.seq(tok(';'), prologueDecls, Parser.not(Parser.eof)),
2149
+ { min: 1 },
2150
+ ),
2151
+ ),
2152
+ ),
2153
+ Parser.seq(
2154
+ Parser.opt(Parser.seq(tok(';'), prologueDecls)),
2155
+ Parser.alt(Parser.eof, unexpectedHere<void>("';'")),
2156
+ ),
2157
+ ),
2158
+ ).pipe(
2159
+ Parser.map((ops) =>
2160
+ Ast.update(
2161
+ Option.getOrElse(ops, () => []),
2162
+ prologue.value(),
2163
+ ),
2164
+ ),
2165
+ ),
2166
+ );
2167
+
2168
+ // -----------------------------------------------------------------------------
2169
+ // Entry points
2170
+ // -----------------------------------------------------------------------------
2171
+
2172
+ const run = <A>(
2173
+ grammar: P<A>,
2174
+ input: string,
2175
+ baseIri: Option.Option<string>,
2176
+ prefixes: Readonly<Record<string, string>>,
2177
+ ): Result.Result<A, Failure> => {
2178
+ const tokens = tokenize(input);
2179
+ const resolved = resolve(tokens, baseIri, prefixes);
2180
+ fresh = () => new Context(input);
2181
+ ctx = fresh();
2182
+ prologue = {
2183
+ value: () => {
2184
+ const declared: Ast.Prologue = { prefixes: { ...resolved.prefixes } };
2185
+ const based = Option.isNone(resolved.base)
2186
+ ? declared
2187
+ : { ...declared, base: resolved.base.value };
2188
+ return Option.isNone(ctx.version) ? based : { ...based, version: ctx.version.value };
2189
+ },
2190
+ };
2191
+ // A `Failure` thrown by the maps that check what they build ends the parse.
2192
+ const parsed = catchFailure(() => Parser.parse(grammar, tokens));
2193
+ if (Result.isFailure(parsed)) return Result.fail(parsed.failure);
2194
+ const result: Result.Result<A, ParseError.ParseError<Failure>> = parsed.success;
2195
+ if (Result.isSuccess(result)) return Result.succeed(result.success);
2196
+ const error: ParseError.ParseError<Failure> = result.failure;
2197
+ if (error.cause !== undefined) return Result.fail(error.cause);
2198
+ const t = tokenAt(tokens, error.offset);
2199
+ if (t.type === 'ERROR') return Result.fail(new Failure(t.value, t.start));
2200
+ return Result.fail(new Failure(`Unexpected ${describe(t)}`, offsetOf(t)));
2201
+ };
2202
+
2203
+ /** Parses a query against a base IRI (if any) and initial prefixes. */
2204
+ export const parseQuery = (
2205
+ input: string,
2206
+ baseIri: Option.Option<string>,
2207
+ prefixes: Readonly<Record<string, string>>,
2208
+ ): Result.Result<Ast.Query, Failure> => run(queryUnit, input, baseIri, prefixes);
2209
+
2210
+ /** Parses an update request against a base IRI (if any) and initial prefixes. */
2211
+ export const parseUpdate = (
2212
+ input: string,
2213
+ baseIri: Option.Option<string>,
2214
+ prefixes: Readonly<Record<string, string>>,
2215
+ ): Result.Result<Ast.Update, Failure> => run(updateUnit, input, baseIri, prefixes);