@graphty/graph-io 0.3.24 → 0.3.26

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 (581) hide show
  1. package/README.md +49 -414
  2. package/dist/chunks/children-CL3Cy0ez.js.map +1 -1
  3. package/dist/chunks/choose-BbJI55dx.js +56 -0
  4. package/dist/chunks/choose-BbJI55dx.js.map +1 -0
  5. package/dist/chunks/constants-BCsFsMj4.js +231 -0
  6. package/dist/chunks/constants-BCsFsMj4.js.map +1 -0
  7. package/dist/chunks/{escape-B-tkk_Cl.js → escape-D0g6NNUy.js} +382 -92
  8. package/dist/chunks/escape-D0g6NNUy.js.map +1 -0
  9. package/dist/chunks/export-BTI4yQgy.js +4333 -0
  10. package/dist/chunks/export-BTI4yQgy.js.map +1 -0
  11. package/dist/chunks/exporter-BMqk5oxW.js +3465 -0
  12. package/dist/chunks/exporter-BMqk5oxW.js.map +1 -0
  13. package/dist/chunks/{importer-eUREhBGj.js → exporter-Cra2GYcN.js} +4969 -3201
  14. package/dist/chunks/exporter-Cra2GYcN.js.map +1 -0
  15. package/dist/chunks/{exporter-BGrsWamJ.js → exporter-Dxh231ZF.js} +38 -229
  16. package/dist/chunks/exporter-Dxh231ZF.js.map +1 -0
  17. package/dist/chunks/{exporter-DIeGJXAZ.js → exporter-tne475KK.js} +22 -20
  18. package/dist/chunks/exporter-tne475KK.js.map +1 -0
  19. package/dist/chunks/importer-90YWhJoF.js +2811 -0
  20. package/dist/chunks/importer-90YWhJoF.js.map +1 -0
  21. package/dist/chunks/{importer-D_e7e7LX.js → importer-Bcl1d4xH.js} +398 -145
  22. package/dist/chunks/importer-Bcl1d4xH.js.map +1 -0
  23. package/dist/chunks/{importer-BWY2FFc5.js → importer-BfIsp1f9.js} +255 -77
  24. package/dist/chunks/importer-BfIsp1f9.js.map +1 -0
  25. package/dist/chunks/{importer-zGLo8Dg_.js → importer-C_TEA1zJ.js} +484 -157
  26. package/dist/chunks/importer-C_TEA1zJ.js.map +1 -0
  27. package/dist/chunks/{importer-DET1tg6s.js → importer-DCjOvO7U.js} +1687 -310
  28. package/dist/chunks/importer-DCjOvO7U.js.map +1 -0
  29. package/dist/chunks/{importer-vi3bSdtw.js → importer-DfVu6j59.js} +509 -76
  30. package/dist/chunks/importer-DfVu6j59.js.map +1 -0
  31. package/dist/chunks/{importer-DIrbbnAf.js → importer-Dku_VAIY.js} +585 -226
  32. package/dist/chunks/importer-Dku_VAIY.js.map +1 -0
  33. package/dist/chunks/json-elements-3tnyt5uZ.js +1225 -0
  34. package/dist/chunks/json-elements-3tnyt5uZ.js.map +1 -0
  35. package/dist/chunks/ontology-export-B9Tcf37D.js +357 -0
  36. package/dist/chunks/ontology-export-B9Tcf37D.js.map +1 -0
  37. package/dist/chunks/{records-dbRkxwaq.js → records-CQXT__mY.js} +298 -114
  38. package/dist/chunks/records-CQXT__mY.js.map +1 -0
  39. package/dist/chunks/{text-Dr0Ifpag.js → text-DmcUs5_Q.js} +29 -11
  40. package/dist/chunks/text-DmcUs5_Q.js.map +1 -0
  41. package/dist/chunks/{writer-C7flM-Ih.js → writer-DxjgHwSe.js} +19 -1
  42. package/dist/chunks/writer-DxjgHwSe.js.map +1 -0
  43. package/dist/csv.js +951 -261
  44. package/dist/csv.js.map +1 -1
  45. package/dist/cx.js +6 -3
  46. package/dist/cx2.js +2 -2
  47. package/dist/cys.js +6 -3
  48. package/dist/dot.js +1 -1
  49. package/dist/gexf.js +554 -122
  50. package/dist/gexf.js.map +1 -1
  51. package/dist/gml.js +342 -85
  52. package/dist/gml.js.map +1 -1
  53. package/dist/graph-io.js +1105 -213
  54. package/dist/graph-io.js.map +1 -1
  55. package/dist/graphml.js +3 -2
  56. package/dist/graphml.js.map +1 -1
  57. package/dist/json.js +3 -2
  58. package/dist/neo4j.js +564 -157
  59. package/dist/neo4j.js.map +1 -1
  60. package/dist/obo.js +6 -3
  61. package/dist/pajek.js +1 -1
  62. package/dist/src/children.d.ts +18 -6
  63. package/dist/src/children.d.ts.map +1 -1
  64. package/dist/src/children.js +6 -3
  65. package/dist/src/children.js.map +1 -1
  66. package/dist/src/common/attributes.d.ts +29 -11
  67. package/dist/src/common/attributes.d.ts.map +1 -1
  68. package/dist/src/common/attributes.js +25 -7
  69. package/dist/src/common/attributes.js.map +1 -1
  70. package/dist/src/common/cell-budget.d.ts +9 -2
  71. package/dist/src/common/cell-budget.d.ts.map +1 -1
  72. package/dist/src/common/cell-budget.js +11 -3
  73. package/dist/src/common/cell-budget.js.map +1 -1
  74. package/dist/src/common/choose.d.ts +19 -0
  75. package/dist/src/common/choose.d.ts.map +1 -0
  76. package/dist/src/common/choose.js +72 -0
  77. package/dist/src/common/choose.js.map +1 -0
  78. package/dist/src/common/codes.d.ts +456 -66
  79. package/dist/src/common/codes.d.ts.map +1 -1
  80. package/dist/src/common/codes.js +458 -66
  81. package/dist/src/common/codes.js.map +1 -1
  82. package/dist/src/common/compare.d.ts +81 -0
  83. package/dist/src/common/compare.d.ts.map +1 -0
  84. package/dist/src/common/compare.js +394 -0
  85. package/dist/src/common/compare.js.map +1 -0
  86. package/dist/src/common/cx-export.d.ts +123 -0
  87. package/dist/src/common/cx-export.d.ts.map +1 -0
  88. package/dist/src/common/cx-export.js +334 -0
  89. package/dist/src/common/cx-export.js.map +1 -0
  90. package/dist/src/common/declared-types.d.ts +22 -2
  91. package/dist/src/common/declared-types.d.ts.map +1 -1
  92. package/dist/src/common/declared-types.js +19 -1
  93. package/dist/src/common/declared-types.js.map +1 -1
  94. package/dist/src/common/direction.d.ts +74 -50
  95. package/dist/src/common/direction.d.ts.map +1 -1
  96. package/dist/src/common/direction.js +47 -27
  97. package/dist/src/common/direction.js.map +1 -1
  98. package/dist/src/common/escape.d.ts +21 -9
  99. package/dist/src/common/escape.d.ts.map +1 -1
  100. package/dist/src/common/escape.js +33 -17
  101. package/dist/src/common/escape.js.map +1 -1
  102. package/dist/src/common/export.d.ts +144 -32
  103. package/dist/src/common/export.d.ts.map +1 -1
  104. package/dist/src/common/export.js +216 -42
  105. package/dist/src/common/export.js.map +1 -1
  106. package/dist/src/common/format.d.ts +23 -1
  107. package/dist/src/common/format.d.ts.map +1 -1
  108. package/dist/src/common/format.js +26 -1
  109. package/dist/src/common/format.js.map +1 -1
  110. package/dist/src/common/ids.d.ts +9 -2
  111. package/dist/src/common/ids.d.ts.map +1 -1
  112. package/dist/src/common/ids.js +6 -2
  113. package/dist/src/common/ids.js.map +1 -1
  114. package/dist/src/common/input.d.ts +122 -28
  115. package/dist/src/common/input.d.ts.map +1 -1
  116. package/dist/src/common/input.js +890 -124
  117. package/dist/src/common/input.js.map +1 -1
  118. package/dist/src/common/json-elements.d.ts +144 -20
  119. package/dist/src/common/json-elements.d.ts.map +1 -1
  120. package/dist/src/common/json-elements.js +868 -188
  121. package/dist/src/common/json-elements.js.map +1 -1
  122. package/dist/src/common/line-format.d.ts +90 -0
  123. package/dist/src/common/line-format.d.ts.map +1 -0
  124. package/dist/src/common/line-format.js +185 -0
  125. package/dist/src/common/line-format.js.map +1 -0
  126. package/dist/src/common/lists.d.ts +6 -1
  127. package/dist/src/common/lists.d.ts.map +1 -1
  128. package/dist/src/common/lists.js +2 -0
  129. package/dist/src/common/lists.js.map +1 -1
  130. package/dist/src/common/ontology-export.d.ts +167 -0
  131. package/dist/src/common/ontology-export.d.ts.map +1 -0
  132. package/dist/src/common/ontology-export.js +359 -0
  133. package/dist/src/common/ontology-export.js.map +1 -0
  134. package/dist/src/common/ontology.d.ts +25 -3
  135. package/dist/src/common/ontology.d.ts.map +1 -1
  136. package/dist/src/common/ontology.js +30 -9
  137. package/dist/src/common/ontology.js.map +1 -1
  138. package/dist/src/common/options.d.ts +62 -12
  139. package/dist/src/common/options.d.ts.map +1 -1
  140. package/dist/src/common/options.js +89 -11
  141. package/dist/src/common/options.js.map +1 -1
  142. package/dist/src/common/plural.d.ts +31 -0
  143. package/dist/src/common/plural.d.ts.map +1 -0
  144. package/dist/src/common/plural.js +46 -0
  145. package/dist/src/common/plural.js.map +1 -0
  146. package/dist/src/common/report.d.ts +72 -14
  147. package/dist/src/common/report.d.ts.map +1 -1
  148. package/dist/src/common/report.js +146 -22
  149. package/dist/src/common/report.js.map +1 -1
  150. package/dist/src/common/temporal.d.ts +22 -5
  151. package/dist/src/common/temporal.d.ts.map +1 -1
  152. package/dist/src/common/temporal.js +13 -2
  153. package/dist/src/common/temporal.js.map +1 -1
  154. package/dist/src/common/text.d.ts +39 -23
  155. package/dist/src/common/text.d.ts.map +1 -1
  156. package/dist/src/common/text.js +51 -21
  157. package/dist/src/common/text.js.map +1 -1
  158. package/dist/src/common/weights.d.ts +37 -4
  159. package/dist/src/common/weights.d.ts.map +1 -1
  160. package/dist/src/common/weights.js +61 -2
  161. package/dist/src/common/weights.js.map +1 -1
  162. package/dist/src/common/writer.d.ts +19 -3
  163. package/dist/src/common/writer.d.ts.map +1 -1
  164. package/dist/src/common/writer.js +30 -2
  165. package/dist/src/common/writer.js.map +1 -1
  166. package/dist/src/common/xml.d.ts +125 -9
  167. package/dist/src/common/xml.d.ts.map +1 -1
  168. package/dist/src/common/xml.js +400 -83
  169. package/dist/src/common/xml.js.map +1 -1
  170. package/dist/src/common/zip.d.ts +44 -4
  171. package/dist/src/common/zip.d.ts.map +1 -1
  172. package/dist/src/common/zip.js +134 -5
  173. package/dist/src/common/zip.js.map +1 -1
  174. package/dist/src/formats/csv/exporter.d.ts +80 -24
  175. package/dist/src/formats/csv/exporter.d.ts.map +1 -1
  176. package/dist/src/formats/csv/exporter.js +145 -32
  177. package/dist/src/formats/csv/exporter.js.map +1 -1
  178. package/dist/src/formats/csv/header.d.ts +38 -9
  179. package/dist/src/formats/csv/header.d.ts.map +1 -1
  180. package/dist/src/formats/csv/header.js +46 -10
  181. package/dist/src/formats/csv/header.js.map +1 -1
  182. package/dist/src/formats/csv/importer.d.ts +187 -37
  183. package/dist/src/formats/csv/importer.d.ts.map +1 -1
  184. package/dist/src/formats/csv/importer.js +835 -204
  185. package/dist/src/formats/csv/importer.js.map +1 -1
  186. package/dist/src/formats/csv/index.d.ts +100 -19
  187. package/dist/src/formats/csv/index.d.ts.map +1 -1
  188. package/dist/src/formats/csv/index.js +94 -21
  189. package/dist/src/formats/csv/index.js.map +1 -1
  190. package/dist/src/formats/csv/records.d.ts +95 -10
  191. package/dist/src/formats/csv/records.d.ts.map +1 -1
  192. package/dist/src/formats/csv/records.js +333 -122
  193. package/dist/src/formats/csv/records.js.map +1 -1
  194. package/dist/src/formats/csv/values.d.ts +1 -0
  195. package/dist/src/formats/csv/values.d.ts.map +1 -1
  196. package/dist/src/formats/csv/values.js +1 -0
  197. package/dist/src/formats/csv/values.js.map +1 -1
  198. package/dist/src/formats/cx/exporter.d.ts +102 -0
  199. package/dist/src/formats/cx/exporter.d.ts.map +1 -0
  200. package/dist/src/formats/cx/exporter.js +1217 -0
  201. package/dist/src/formats/cx/exporter.js.map +1 -0
  202. package/dist/src/formats/cx/importer.d.ts +79 -32
  203. package/dist/src/formats/cx/importer.d.ts.map +1 -1
  204. package/dist/src/formats/cx/importer.js +680 -285
  205. package/dist/src/formats/cx/importer.js.map +1 -1
  206. package/dist/src/formats/cx/index.d.ts +4 -3
  207. package/dist/src/formats/cx/index.d.ts.map +1 -1
  208. package/dist/src/formats/cx/index.js +4 -3
  209. package/dist/src/formats/cx/index.js.map +1 -1
  210. package/dist/src/formats/cx2/exporter.d.ts +29 -11
  211. package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
  212. package/dist/src/formats/cx2/exporter.js +39 -268
  213. package/dist/src/formats/cx2/exporter.js.map +1 -1
  214. package/dist/src/formats/cx2/importer.d.ts +78 -28
  215. package/dist/src/formats/cx2/importer.d.ts.map +1 -1
  216. package/dist/src/formats/cx2/importer.js +226 -79
  217. package/dist/src/formats/cx2/importer.js.map +1 -1
  218. package/dist/src/formats/cx2/index.d.ts +2 -1
  219. package/dist/src/formats/cx2/index.d.ts.map +1 -1
  220. package/dist/src/formats/cx2/index.js +2 -1
  221. package/dist/src/formats/cx2/index.js.map +1 -1
  222. package/dist/src/formats/cys/constants.d.ts +66 -17
  223. package/dist/src/formats/cys/constants.d.ts.map +1 -1
  224. package/dist/src/formats/cys/constants.js +59 -18
  225. package/dist/src/formats/cys/constants.js.map +1 -1
  226. package/dist/src/formats/cys/exporter.d.ts +118 -0
  227. package/dist/src/formats/cys/exporter.d.ts.map +1 -0
  228. package/dist/src/formats/cys/exporter.js +1072 -0
  229. package/dist/src/formats/cys/exporter.js.map +1 -0
  230. package/dist/src/formats/cys/importer.d.ts +22 -8
  231. package/dist/src/formats/cys/importer.d.ts.map +1 -1
  232. package/dist/src/formats/cys/importer.js +510 -149
  233. package/dist/src/formats/cys/importer.js.map +1 -1
  234. package/dist/src/formats/cys/index.d.ts +4 -2
  235. package/dist/src/formats/cys/index.d.ts.map +1 -1
  236. package/dist/src/formats/cys/index.js +4 -2
  237. package/dist/src/formats/cys/index.js.map +1 -1
  238. package/dist/src/formats/cys/session.d.ts +46 -7
  239. package/dist/src/formats/cys/session.d.ts.map +1 -1
  240. package/dist/src/formats/cys/session.js +98 -24
  241. package/dist/src/formats/cys/session.js.map +1 -1
  242. package/dist/src/formats/cys/tables.d.ts +9 -2
  243. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  244. package/dist/src/formats/cys/tables.js +29 -7
  245. package/dist/src/formats/cys/tables.js.map +1 -1
  246. package/dist/src/formats/dot/exporter.d.ts +42 -14
  247. package/dist/src/formats/dot/exporter.d.ts.map +1 -1
  248. package/dist/src/formats/dot/exporter.js +56 -29
  249. package/dist/src/formats/dot/exporter.js.map +1 -1
  250. package/dist/src/formats/dot/importer.d.ts +91 -29
  251. package/dist/src/formats/dot/importer.d.ts.map +1 -1
  252. package/dist/src/formats/dot/importer.js +190 -39
  253. package/dist/src/formats/dot/importer.js.map +1 -1
  254. package/dist/src/formats/dot/index.d.ts +2 -1
  255. package/dist/src/formats/dot/index.d.ts.map +1 -1
  256. package/dist/src/formats/dot/index.js +2 -1
  257. package/dist/src/formats/dot/index.js.map +1 -1
  258. package/dist/src/formats/dot/names.d.ts +44 -11
  259. package/dist/src/formats/dot/names.d.ts.map +1 -1
  260. package/dist/src/formats/dot/names.js +44 -11
  261. package/dist/src/formats/dot/names.js.map +1 -1
  262. package/dist/src/formats/dot/tokenizer.d.ts +9 -2
  263. package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
  264. package/dist/src/formats/dot/tokenizer.js +20 -5
  265. package/dist/src/formats/dot/tokenizer.js.map +1 -1
  266. package/dist/src/formats/gexf/exporter.d.ts +46 -15
  267. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  268. package/dist/src/formats/gexf/exporter.js +45 -15
  269. package/dist/src/formats/gexf/exporter.js.map +1 -1
  270. package/dist/src/formats/gexf/importer.d.ts +87 -23
  271. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  272. package/dist/src/formats/gexf/importer.js +471 -90
  273. package/dist/src/formats/gexf/importer.js.map +1 -1
  274. package/dist/src/formats/gexf/index.d.ts +84 -21
  275. package/dist/src/formats/gexf/index.d.ts.map +1 -1
  276. package/dist/src/formats/gexf/index.js +80 -23
  277. package/dist/src/formats/gexf/index.js.map +1 -1
  278. package/dist/src/formats/gexf/schema.d.ts +67 -15
  279. package/dist/src/formats/gexf/schema.d.ts.map +1 -1
  280. package/dist/src/formats/gexf/schema.js +59 -13
  281. package/dist/src/formats/gexf/schema.js.map +1 -1
  282. package/dist/src/formats/gml/exporter.d.ts +69 -21
  283. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  284. package/dist/src/formats/gml/exporter.js +74 -29
  285. package/dist/src/formats/gml/exporter.js.map +1 -1
  286. package/dist/src/formats/gml/importer.d.ts +116 -25
  287. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  288. package/dist/src/formats/gml/importer.js +290 -61
  289. package/dist/src/formats/gml/importer.js.map +1 -1
  290. package/dist/src/formats/gml/index.d.ts +87 -24
  291. package/dist/src/formats/gml/index.d.ts.map +1 -1
  292. package/dist/src/formats/gml/index.js +79 -26
  293. package/dist/src/formats/gml/index.js.map +1 -1
  294. package/dist/src/formats/gml/syntax.d.ts +67 -18
  295. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  296. package/dist/src/formats/gml/syntax.js +108 -26
  297. package/dist/src/formats/gml/syntax.js.map +1 -1
  298. package/dist/src/formats/graphml/constants.d.ts +174 -44
  299. package/dist/src/formats/graphml/constants.d.ts.map +1 -1
  300. package/dist/src/formats/graphml/constants.js +165 -44
  301. package/dist/src/formats/graphml/constants.js.map +1 -1
  302. package/dist/src/formats/graphml/exporter.d.ts +17 -9
  303. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  304. package/dist/src/formats/graphml/exporter.js +33 -12
  305. package/dist/src/formats/graphml/exporter.js.map +1 -1
  306. package/dist/src/formats/graphml/importer.d.ts +19 -7
  307. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  308. package/dist/src/formats/graphml/importer.js +466 -39
  309. package/dist/src/formats/graphml/importer.js.map +1 -1
  310. package/dist/src/formats/graphml/index.d.ts +2 -1
  311. package/dist/src/formats/graphml/index.d.ts.map +1 -1
  312. package/dist/src/formats/graphml/index.js +2 -1
  313. package/dist/src/formats/graphml/index.js.map +1 -1
  314. package/dist/src/formats/graphml/tree.d.ts +6 -2
  315. package/dist/src/formats/graphml/tree.d.ts.map +1 -1
  316. package/dist/src/formats/graphml/tree.js +6 -2
  317. package/dist/src/formats/graphml/tree.js.map +1 -1
  318. package/dist/src/formats/graphml/yfiles.d.ts +8 -3
  319. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  320. package/dist/src/formats/graphml/yfiles.js +36 -15
  321. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  322. package/dist/src/formats/json/dialect.d.ts +88 -24
  323. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  324. package/dist/src/formats/json/dialect.js +109 -19
  325. package/dist/src/formats/json/dialect.js.map +1 -1
  326. package/dist/src/formats/json/exporter.d.ts +134 -22
  327. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  328. package/dist/src/formats/json/exporter.js +135 -54
  329. package/dist/src/formats/json/exporter.js.map +1 -1
  330. package/dist/src/formats/json/importer.d.ts +173 -52
  331. package/dist/src/formats/json/importer.d.ts.map +1 -1
  332. package/dist/src/formats/json/importer.js +899 -220
  333. package/dist/src/formats/json/importer.js.map +1 -1
  334. package/dist/src/formats/json/index.d.ts +3 -2
  335. package/dist/src/formats/json/index.d.ts.map +1 -1
  336. package/dist/src/formats/json/index.js +3 -2
  337. package/dist/src/formats/json/index.js.map +1 -1
  338. package/dist/src/formats/json/obographs-export.d.ts +68 -0
  339. package/dist/src/formats/json/obographs-export.d.ts.map +1 -0
  340. package/dist/src/formats/json/obographs-export.js +941 -0
  341. package/dist/src/formats/json/obographs-export.js.map +1 -0
  342. package/dist/src/formats/json/obographs.d.ts +26 -0
  343. package/dist/src/formats/json/obographs.d.ts.map +1 -1
  344. package/dist/src/formats/json/obographs.js +297 -80
  345. package/dist/src/formats/json/obographs.js.map +1 -1
  346. package/dist/src/formats/neo4j/exporter.d.ts +109 -21
  347. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  348. package/dist/src/formats/neo4j/exporter.js +238 -85
  349. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  350. package/dist/src/formats/neo4j/header.d.ts +17 -4
  351. package/dist/src/formats/neo4j/header.d.ts.map +1 -1
  352. package/dist/src/formats/neo4j/header.js +36 -4
  353. package/dist/src/formats/neo4j/header.js.map +1 -1
  354. package/dist/src/formats/neo4j/importer.d.ts +107 -27
  355. package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
  356. package/dist/src/formats/neo4j/importer.js +415 -63
  357. package/dist/src/formats/neo4j/importer.js.map +1 -1
  358. package/dist/src/formats/neo4j/index.d.ts +73 -23
  359. package/dist/src/formats/neo4j/index.d.ts.map +1 -1
  360. package/dist/src/formats/neo4j/index.js +65 -25
  361. package/dist/src/formats/neo4j/index.js.map +1 -1
  362. package/dist/src/formats/obo/exporter.d.ts +150 -0
  363. package/dist/src/formats/obo/exporter.d.ts.map +1 -0
  364. package/dist/src/formats/obo/exporter.js +1736 -0
  365. package/dist/src/formats/obo/exporter.js.map +1 -0
  366. package/dist/src/formats/obo/importer.d.ts +95 -19
  367. package/dist/src/formats/obo/importer.d.ts.map +1 -1
  368. package/dist/src/formats/obo/importer.js +475 -104
  369. package/dist/src/formats/obo/importer.js.map +1 -1
  370. package/dist/src/formats/obo/index.d.ts +6 -3
  371. package/dist/src/formats/obo/index.d.ts.map +1 -1
  372. package/dist/src/formats/obo/index.js +6 -3
  373. package/dist/src/formats/obo/index.js.map +1 -1
  374. package/dist/src/formats/obo/syntax.d.ts +108 -4
  375. package/dist/src/formats/obo/syntax.d.ts.map +1 -1
  376. package/dist/src/formats/obo/syntax.js +211 -34
  377. package/dist/src/formats/obo/syntax.js.map +1 -1
  378. package/dist/src/formats/pajek/exporter.d.ts +54 -16
  379. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  380. package/dist/src/formats/pajek/exporter.js +66 -34
  381. package/dist/src/formats/pajek/exporter.js.map +1 -1
  382. package/dist/src/formats/pajek/importer.d.ts +84 -22
  383. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  384. package/dist/src/formats/pajek/importer.js +303 -83
  385. package/dist/src/formats/pajek/importer.js.map +1 -1
  386. package/dist/src/formats/pajek/index.d.ts +2 -1
  387. package/dist/src/formats/pajek/index.d.ts.map +1 -1
  388. package/dist/src/formats/pajek/index.js +2 -1
  389. package/dist/src/formats/pajek/index.js.map +1 -1
  390. package/dist/src/formats/pajek/syntax.d.ts +77 -14
  391. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  392. package/dist/src/formats/pajek/syntax.js +183 -51
  393. package/dist/src/formats/pajek/syntax.js.map +1 -1
  394. package/dist/src/formats/xgmml/columns.d.ts +1 -0
  395. package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
  396. package/dist/src/formats/xgmml/columns.js +4 -0
  397. package/dist/src/formats/xgmml/columns.js.map +1 -1
  398. package/dist/src/formats/xgmml/constants.d.ts +186 -56
  399. package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
  400. package/dist/src/formats/xgmml/constants.js +181 -57
  401. package/dist/src/formats/xgmml/constants.js.map +1 -1
  402. package/dist/src/formats/xgmml/document.d.ts +65 -11
  403. package/dist/src/formats/xgmml/document.d.ts.map +1 -1
  404. package/dist/src/formats/xgmml/document.js +157 -28
  405. package/dist/src/formats/xgmml/document.js.map +1 -1
  406. package/dist/src/formats/xgmml/emit.d.ts +61 -3
  407. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  408. package/dist/src/formats/xgmml/emit.js +129 -26
  409. package/dist/src/formats/xgmml/emit.js.map +1 -1
  410. package/dist/src/formats/xgmml/exporter.d.ts +13 -6
  411. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  412. package/dist/src/formats/xgmml/exporter.js +20 -21
  413. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  414. package/dist/src/formats/xgmml/importer.d.ts +33 -12
  415. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  416. package/dist/src/formats/xgmml/importer.js +35 -72
  417. package/dist/src/formats/xgmml/importer.js.map +1 -1
  418. package/dist/src/formats/xgmml/index.d.ts +1 -0
  419. package/dist/src/formats/xgmml/index.d.ts.map +1 -1
  420. package/dist/src/formats/xgmml/index.js +1 -0
  421. package/dist/src/formats/xgmml/index.js.map +1 -1
  422. package/dist/src/formats/xgmml/values.d.ts +8 -1
  423. package/dist/src/formats/xgmml/values.d.ts.map +1 -1
  424. package/dist/src/formats/xgmml/values.js +7 -2
  425. package/dist/src/formats/xgmml/values.js.map +1 -1
  426. package/dist/src/index.d.ts +23 -18
  427. package/dist/src/index.d.ts.map +1 -1
  428. package/dist/src/index.js +28 -16
  429. package/dist/src/index.js.map +1 -1
  430. package/dist/src/registry.d.ts +478 -92
  431. package/dist/src/registry.d.ts.map +1 -1
  432. package/dist/src/registry.js +807 -88
  433. package/dist/src/registry.js.map +1 -1
  434. package/dist/src/sniff.d.ts +61 -19
  435. package/dist/src/sniff.d.ts.map +1 -1
  436. package/dist/src/sniff.js +121 -29
  437. package/dist/src/sniff.js.map +1 -1
  438. package/dist/src/types.d.ts +362 -112
  439. package/dist/src/types.d.ts.map +1 -1
  440. package/dist/src/types.js +28 -7
  441. package/dist/src/types.js.map +1 -1
  442. package/dist/xgmml.js +2 -2
  443. package/docs/samples/README.md +25 -0
  444. package/docs/samples/got-edges.csv +353 -0
  445. package/docs/samples/got-network.graphml +1384 -0
  446. package/docs/samples/got-nodes.csv +108 -0
  447. package/docs/samples/got.cx +930 -0
  448. package/docs/samples/got.cx2 +465 -0
  449. package/docs/samples/got.gexf +471 -0
  450. package/docs/samples/got.gml +2650 -0
  451. package/docs/samples/got.json +2546 -0
  452. package/docs/samples/got.net +461 -0
  453. package/docs/samples/movies-nodes.csv +9 -0
  454. package/docs/samples/movies-rels.csv +8 -0
  455. package/docs/samples/networks.cys +0 -0
  456. package/docs/samples/proteins.xgmml +9 -0
  457. package/docs/samples/teams.gv +24 -0
  458. package/docs/samples/vehicles.obo +25 -0
  459. package/package.json +9 -4
  460. package/src/children.ts +18 -6
  461. package/src/common/attributes.ts +29 -11
  462. package/src/common/cell-budget.ts +11 -3
  463. package/src/common/choose.ts +89 -0
  464. package/src/common/codes.ts +490 -66
  465. package/src/common/compare.ts +472 -0
  466. package/src/common/cx-export.ts +432 -0
  467. package/src/common/declared-types.ts +38 -4
  468. package/src/common/direction.ts +78 -51
  469. package/src/common/escape.ts +33 -17
  470. package/src/common/export.ts +284 -47
  471. package/src/common/format.ts +30 -1
  472. package/src/common/ids.ts +14 -3
  473. package/src/common/input.ts +1057 -134
  474. package/src/common/json-elements.ts +1034 -198
  475. package/src/common/line-format.ts +249 -0
  476. package/src/common/lists.ts +6 -1
  477. package/src/common/ontology-export.ts +461 -0
  478. package/src/common/ontology.ts +31 -9
  479. package/src/common/options.ts +110 -15
  480. package/src/common/plural.ts +49 -0
  481. package/src/common/report.ts +168 -25
  482. package/src/common/temporal.ts +22 -5
  483. package/src/common/text.ts +62 -23
  484. package/src/common/weights.ts +74 -4
  485. package/src/common/writer.ts +37 -3
  486. package/src/common/xml.ts +477 -88
  487. package/src/common/zip.ts +169 -7
  488. package/src/formats/csv/exporter.ts +201 -46
  489. package/src/formats/csv/header.ts +50 -11
  490. package/src/formats/csv/importer.ts +1133 -245
  491. package/src/formats/csv/index.ts +106 -19
  492. package/src/formats/csv/records.ts +396 -122
  493. package/src/formats/csv/values.ts +1 -0
  494. package/src/formats/cx/exporter.ts +1483 -0
  495. package/src/formats/cx/importer.ts +888 -300
  496. package/src/formats/cx/index.ts +4 -3
  497. package/src/formats/cx2/exporter.ts +61 -338
  498. package/src/formats/cx2/importer.ts +317 -86
  499. package/src/formats/cx2/index.ts +2 -1
  500. package/src/formats/cys/constants.ts +62 -17
  501. package/src/formats/cys/exporter.ts +1368 -0
  502. package/src/formats/cys/importer.ts +659 -157
  503. package/src/formats/cys/index.ts +4 -2
  504. package/src/formats/cys/session.ts +139 -31
  505. package/src/formats/cys/tables.ts +47 -9
  506. package/src/formats/dot/exporter.ts +83 -37
  507. package/src/formats/dot/importer.ts +248 -54
  508. package/src/formats/dot/index.ts +2 -1
  509. package/src/formats/dot/names.ts +44 -11
  510. package/src/formats/dot/tokenizer.ts +25 -6
  511. package/src/formats/gexf/exporter.ts +57 -18
  512. package/src/formats/gexf/importer.ts +636 -105
  513. package/src/formats/gexf/index.ts +90 -21
  514. package/src/formats/gexf/schema.ts +67 -15
  515. package/src/formats/gml/exporter.ts +90 -36
  516. package/src/formats/gml/importer.ts +388 -67
  517. package/src/formats/gml/index.ts +85 -24
  518. package/src/formats/gml/syntax.ts +111 -26
  519. package/src/formats/graphml/constants.ts +178 -44
  520. package/src/formats/graphml/exporter.ts +52 -18
  521. package/src/formats/graphml/importer.ts +640 -60
  522. package/src/formats/graphml/index.ts +2 -1
  523. package/src/formats/graphml/tree.ts +6 -2
  524. package/src/formats/graphml/yfiles.ts +37 -15
  525. package/src/formats/json/dialect.ts +128 -29
  526. package/src/formats/json/exporter.ts +205 -68
  527. package/src/formats/json/importer.ts +1163 -253
  528. package/src/formats/json/index.ts +3 -1
  529. package/src/formats/json/obographs-export.ts +1197 -0
  530. package/src/formats/json/obographs.ts +353 -92
  531. package/src/formats/neo4j/exporter.ts +320 -101
  532. package/src/formats/neo4j/header.ts +44 -6
  533. package/src/formats/neo4j/importer.ts +512 -73
  534. package/src/formats/neo4j/index.ts +75 -23
  535. package/src/formats/obo/exporter.ts +2210 -0
  536. package/src/formats/obo/importer.ts +622 -109
  537. package/src/formats/obo/index.ts +6 -3
  538. package/src/formats/obo/syntax.ts +232 -37
  539. package/src/formats/pajek/exporter.ts +89 -41
  540. package/src/formats/pajek/importer.ts +407 -93
  541. package/src/formats/pajek/index.ts +2 -1
  542. package/src/formats/pajek/syntax.ts +213 -52
  543. package/src/formats/xgmml/columns.ts +10 -0
  544. package/src/formats/xgmml/constants.ts +183 -56
  545. package/src/formats/xgmml/document.ts +212 -34
  546. package/src/formats/xgmml/emit.ts +175 -34
  547. package/src/formats/xgmml/exporter.ts +35 -27
  548. package/src/formats/xgmml/importer.ts +64 -86
  549. package/src/formats/xgmml/index.ts +1 -0
  550. package/src/formats/xgmml/values.ts +11 -3
  551. package/src/index.ts +81 -11
  552. package/src/registry.ts +1121 -135
  553. package/src/sniff.ts +163 -32
  554. package/src/types.ts +385 -114
  555. package/dist/chunks/escape-B-tkk_Cl.js.map +0 -1
  556. package/dist/chunks/export-Bh60Dv-n.js +0 -582
  557. package/dist/chunks/export-Bh60Dv-n.js.map +0 -1
  558. package/dist/chunks/exporter-BGrsWamJ.js.map +0 -1
  559. package/dist/chunks/exporter-DIeGJXAZ.js.map +0 -1
  560. package/dist/chunks/importer-BWY2FFc5.js.map +0 -1
  561. package/dist/chunks/importer-DD-xv9_Y.js +0 -1471
  562. package/dist/chunks/importer-DD-xv9_Y.js.map +0 -1
  563. package/dist/chunks/importer-DET1tg6s.js.map +0 -1
  564. package/dist/chunks/importer-DEcKhsmQ.js +0 -1614
  565. package/dist/chunks/importer-DEcKhsmQ.js.map +0 -1
  566. package/dist/chunks/importer-DIrbbnAf.js.map +0 -1
  567. package/dist/chunks/importer-D_e7e7LX.js.map +0 -1
  568. package/dist/chunks/importer-eUREhBGj.js.map +0 -1
  569. package/dist/chunks/importer-vi3bSdtw.js.map +0 -1
  570. package/dist/chunks/importer-zGLo8Dg_.js.map +0 -1
  571. package/dist/chunks/json-elements-DDS8N2Dd.js +0 -779
  572. package/dist/chunks/json-elements-DDS8N2Dd.js.map +0 -1
  573. package/dist/chunks/ontology-BnrJ4I98.js +0 -113
  574. package/dist/chunks/ontology-BnrJ4I98.js.map +0 -1
  575. package/dist/chunks/records-dbRkxwaq.js.map +0 -1
  576. package/dist/chunks/report-B1z4WT9e.js +0 -2372
  577. package/dist/chunks/report-B1z4WT9e.js.map +0 -1
  578. package/dist/chunks/text-Dr0Ifpag.js.map +0 -1
  579. package/dist/chunks/weights-Dzba96G3.js +0 -176
  580. package/dist/chunks/weights-Dzba96G3.js.map +0 -1
  581. package/dist/chunks/writer-C7flM-Ih.js.map +0 -1
@@ -0,0 +1,941 @@
1
+ /**
2
+ * The `obographs` dialect of the JSON exporter: writes a snapshot as an OBO Graphs document
3
+ * (`{ "graphs": [{ "id", "meta", "nodes", "edges", ... }] }`), the JSON form the Gene Ontology and
4
+ * the OBO Foundry publish, and the form the JSON importer's `obographs` dialect reads back.
5
+ *
6
+ * Nodes carry `lbl` from the label column, `type` from the `type` column (Term as CLASS, Instance
7
+ * as INDIVIDUAL, Typedef as PROPERTY) and a `meta` built from the OBO vocabulary columns
8
+ * (src/common/ontology.ts: definition, comments, subsets, xrefs, synonyms, deprecated, and the
9
+ * basicPropertyValues of namespace, alt_id, created_by, creation_date, replaced_by, consider and
10
+ * property_value); any other node column becomes basicPropertyValues named after the column. Edges
11
+ * are `{ sub, pred, obj }` with the edge's `meta` column and its other columns in `meta`. Ids are
12
+ * written as IRIs (`GO:0008150` as `http://purl.obolibrary.org/obo/GO_0008150`, a relation by the
13
+ * IRI of the property whose shorthand it is) whenever the importer compacts the IRI back to the
14
+ * same id. The graph metadata, the PROPERTY nodes, the property edges and the axioms an OBO Graphs
15
+ * import kept in `meta.extra.obographs` are written back.
16
+ */
17
+ import { GraphFormatError } from "@graphty/graph-format";
18
+ import { COLUMN_AS_PROPERTY_VALUE_CODE, DIRECTION_DROPPED_CODE, GRAPH_COLUMN_AS_METADATA_CODE, NODE_ORDER_CODE, NONFINITE_AS_NULL_CODE, RELATION_ASSUMED_CODE, TYPEDEF_NODES_CODE, } from "../../common/codes.js";
19
+ import { pairFolding } from "../../common/direction.js";
20
+ import { LOSS } from "../../common/export.js";
21
+ import { compactOboIri, OBO_IN_OWL, OBO_NODE_COLUMNS, OBO_PURL, OBOGRAPHS_PREDICATE_TAGS, PLACEHOLDER_COLUMN, SYNONYM_SCOPES, } from "../../common/ontology.js";
22
+ import { capabilityNotes, cellOf, emptyColumnNotes, fitsVocabulary, framelessNodes, movedNodes, notePropertyColumn, slotColumn, textOf, UNWRITTEN_ROLES, valuesOf, } from "../../common/ontology-export.js";
23
+ import { agree, plural } from "../../common/plural.js";
24
+ import { explicitWeights } from "../../common/weights.js";
25
+ import { dialectCapabilities, exponentIfUnsafe, isJsonObject } from "./dialect.js";
26
+ import { BUILTIN_PREDICATES, FRAME_TYPES, META_KEYS, NODE_KEYS, PROPERTY_PREDICATES } from "./obographs.js";
27
+ /**
28
+ * The loss codes only the `obographs` dialect records.
29
+ * @category Built-in formats
30
+ */
31
+ export const OBOGRAPHS_LOSS = Object.freeze({
32
+ /** An edge column (or the explicit weights) is written into the edge's `meta` and reads back inside the `meta` column. */
33
+ EDGE_COLUMN_AS_META: "W_OBOGRAPHS_EDGE_COLUMN_AS_META",
34
+ /** A node id or relation is written as an IRI the importer's default `oboIds: "curie"` reads back as a different id. */
35
+ ID_CHANGED: "W_OBOGRAPHS_ID_CHANGED",
36
+ /** A `property_value` with an xsd datatype: basicPropertyValues have no datatype, so it reads back without one. */
37
+ DATATYPE_DROPPED: "W_OBOGRAPHS_DATATYPE_DROPPED",
38
+ });
39
+ /**
40
+ * The codes the dialect shares with the other exporters, under the names JSON_LOSS gives them.
41
+ * @category Built-in formats
42
+ */
43
+ export const OBOGRAPHS_SHARED_LOSS = Object.freeze({
44
+ /** A node column outside the OBO vocabulary reads back inside the `property_value` column. */
45
+ COLUMN_AS_PROPERTY_VALUE: COLUMN_AS_PROPERTY_VALUE_CODE,
46
+ /** An edge without a relation is written with the predicate `is_a`. */
47
+ RELATION_ASSUMED: RELATION_ASSUMED_CODE,
48
+ /** Typedef nodes are written as PROPERTY nodes, which read back as nodes only under `typedefs: "nodes"`. */
49
+ TYPEDEF_NODES: TYPEDEF_NODES_CODE,
50
+ /** A graph attribute is written into the graph's `meta` and reads back in `snapshot.meta.extra.obographs`. */
51
+ GRAPH_COLUMN_AS_METADATA: GRAPH_COLUMN_AS_METADATA_CODE,
52
+ });
53
+ /** The node type of each OBO frame type. */
54
+ const NODE_TYPES = Object.freeze({
55
+ Term: "CLASS",
56
+ Instance: "INDIVIDUAL",
57
+ Typedef: "PROPERTY",
58
+ });
59
+ /** The basicPropertyValues predicate of each OBO tag (the reverse of OBOGRAPHS_PREDICATE_TAGS). */
60
+ const TAG_PREDICATES = new Map([...OBOGRAPHS_PREDICATE_TAGS].map(([pred, tag]) => [tag, pred]));
61
+ /** The OBO Graphs pred of the relations the importer reads from a built-in pred. */
62
+ const REVERSE_PREDICATES = Object.freeze({ is_a: "is_a", instance_of: "type" });
63
+ /** The vocabulary columns the dialect has a place for; every other node column is property values. */
64
+ const PLACED = new Set([
65
+ "type",
66
+ "propertyType",
67
+ "def",
68
+ "def.xrefs",
69
+ "comment",
70
+ "subset",
71
+ "xref",
72
+ "synonym",
73
+ "is_obsolete",
74
+ "namespace",
75
+ "created_by",
76
+ "creation_date",
77
+ "alt_id",
78
+ "replaced_by",
79
+ "consider",
80
+ "property_value",
81
+ "obo.unrecognized",
82
+ ]);
83
+ /** The basicPropertyValues columns, in the order they are written. */
84
+ const PROPERTY_TAGS = [
85
+ "namespace",
86
+ "alt_id",
87
+ "created_by",
88
+ "creation_date",
89
+ "replaced_by",
90
+ "consider",
91
+ ];
92
+ /** An IRI with a scheme. */
93
+ const IRI = /^[A-Za-z][A-Za-z0-9+.-]*:\/\//;
94
+ /** A CURIE whose prefix the OBO PURL mapping keeps (no underscore). */
95
+ const CURIE = /^([A-Za-z][A-Za-z0-9.-]*):(.+)$/;
96
+ /**
97
+ * The records an OBO Graphs import kept under `meta.extra.obographs`.
98
+ * @param snapshot - the snapshot
99
+ * @returns the records, empty when the snapshot did not come from OBO Graphs
100
+ */
101
+ function keptOf(snapshot) {
102
+ const raw = snapshot.meta.extra.obographs;
103
+ const r = isJsonObject(raw) ? raw : {};
104
+ const properties = {};
105
+ if (isJsonObject(r.properties)) {
106
+ for (const [iri, entry] of Object.entries(r.properties)) {
107
+ if (isJsonObject(entry)) {
108
+ properties[iri] = entry;
109
+ }
110
+ }
111
+ }
112
+ return {
113
+ ids: r.ids === "iri" ? "iri" : "curie",
114
+ graph: isJsonObject(r.graph) ? r.graph : {},
115
+ document: isJsonObject(r.document) ? r.document : {},
116
+ properties,
117
+ propertyEdges: Array.isArray(r.propertyEdges) ? r.propertyEdges : [],
118
+ };
119
+ }
120
+ /**
121
+ * The shorthand a property's meta declares (the importer names the property by it).
122
+ * @param meta - the property's meta
123
+ * @returns the shorthand, or null
124
+ */
125
+ function shorthandOf(meta) {
126
+ if (!isJsonObject(meta) || !Array.isArray(meta.basicPropertyValues)) {
127
+ return null;
128
+ }
129
+ for (const pv of meta.basicPropertyValues) {
130
+ if (isJsonObject(pv) &&
131
+ typeof pv.pred === "string" &&
132
+ OBOGRAPHS_PREDICATE_TAGS.get(pv.pred) === "shorthand" &&
133
+ typeof pv.val === "string") {
134
+ return pv.val;
135
+ }
136
+ }
137
+ return null;
138
+ }
139
+ /**
140
+ * The ontology IRI unprefixed ids are written under: the option, the kept graph id, else the OBO
141
+ * PURL of the ontology id (the kept OBO header's, or the graph name's).
142
+ * @param snapshot - the snapshot
143
+ * @param kept - the kept records
144
+ * @param option - the ontologyIri option, or null
145
+ * @returns the IRI
146
+ */
147
+ function ontologyIriOf(snapshot, kept, option) {
148
+ if (option !== null) {
149
+ return option;
150
+ }
151
+ if (typeof kept.graph.id === "string") {
152
+ return kept.graph.id;
153
+ }
154
+ const { obo } = snapshot.meta.extra;
155
+ const header = isJsonObject(obo) && isJsonObject(obo.header) ? obo.header : {};
156
+ const ontology = Array.isArray(header.ontology) && typeof header.ontology[0] === "string" ? header.ontology[0].trim() : null;
157
+ const name = ontology ?? snapshot.meta.name;
158
+ const id = name === null || name.length === 0 ? "graph" : name.replaceAll(/[^A-Za-z0-9_.\-/]/g, "_");
159
+ return `${OBO_PURL}${id}.owl`;
160
+ }
161
+ /**
162
+ * JSON text of a value with -0 kept and the non-finite numbers written as null (counted).
163
+ * @param value - the value
164
+ * @param nonfinite - the counter
165
+ * @param nonfinite.count - the count
166
+ * @returns the JSON text
167
+ */
168
+ function json(value, nonfinite) {
169
+ if (typeof value === "number") {
170
+ if (!Number.isFinite(value)) {
171
+ nonfinite.count++;
172
+ return "null";
173
+ }
174
+ return Object.is(value, -0) ? "-0" : exponentIfUnsafe(JSON.stringify(value));
175
+ }
176
+ if (Array.isArray(value)) {
177
+ return `[${value.map((v) => json(v, nonfinite)).join(",")}]`;
178
+ }
179
+ if (isJsonObject(value)) {
180
+ return `{${Object.entries(value)
181
+ .filter(([, v]) => v !== undefined)
182
+ .map(([k, v]) => `${JSON.stringify(k)}:${json(v, nonfinite)}`)
183
+ .join(",")}}`;
184
+ }
185
+ return JSON.stringify(value) ?? "null";
186
+ }
187
+ /**
188
+ * Whether a value is a non-empty array of strings.
189
+ * @param value - the value
190
+ * @param empty - whether an empty array is allowed
191
+ * @returns true for such an array
192
+ */
193
+ function strings(value, empty = false) {
194
+ return Array.isArray(value) && (empty || value.length > 0) && value.every((v) => typeof v === "string");
195
+ }
196
+ /** One OBO Graphs export: the plan (ids, columns, notes) and the writer. */
197
+ /**
198
+ * The basicPropertyValue texts a property column gives one node: one per item of a list, JSON text
199
+ * for nested values, none when unset.
200
+ * @param column - the column
201
+ * @param i - the node
202
+ * @returns the texts
203
+ */
204
+ function propertyTexts(column, i) {
205
+ const v = cellOf(column, i);
206
+ if (v === undefined) {
207
+ return [];
208
+ }
209
+ if (column.dtype === "list") {
210
+ return v.map((item) => textOf(item, column.child.dtype));
211
+ }
212
+ const nested = column.dtype === "json" || column.meta.components > 1;
213
+ return [nested ? (JSON.stringify(v) ?? "null") : textOf(v, column.dtype)];
214
+ }
215
+ /**
216
+ * The graph columns as basicPropertyValues of the graph's meta.
217
+ * @param snapshot - the snapshot
218
+ * @returns one record per value
219
+ */
220
+ function graphPropertyValues(snapshot) {
221
+ const values = [];
222
+ for (const column of snapshot.graph) {
223
+ const dtype = column.dtype === "list" ? column.child.dtype : column.dtype;
224
+ for (const item of valuesOf(cellOf(column, 0))) {
225
+ values.push({ pred: column.meta.name, val: typeof item === "string" ? item : textOf(item, dtype) });
226
+ }
227
+ }
228
+ return values;
229
+ }
230
+ /**
231
+ * Note a placed node column whose dtype reads back as another.
232
+ * @param note - records a note
233
+ * @param want - the dtype the column reads back as
234
+ * @param column - the column
235
+ */
236
+ function dtypeNote(note, want, column) {
237
+ const listItems = column.dtype === "list" && column.child.dtype !== "string";
238
+ if (((want === "string" || want === "dict") && column.dtype !== want) || listItems) {
239
+ note(LOSS.DTYPE, `node column "${column.meta.name}" holds ${listItems ? "non-string items" : column.dtype}; it reads back as ${listItems ? "string items" : want}`, column.meta.name, column.length - column.nullCount);
240
+ }
241
+ }
242
+ /**
243
+ * The property values of the written nodes that carry an xsd datatype.
244
+ * @param pv - the property_value column
245
+ * @param rows - the written nodes
246
+ * @returns the count
247
+ */
248
+ function countDatatypes(pv, rows) {
249
+ let datatypes = 0;
250
+ for (const i of rows) {
251
+ for (const item of (cellOf(pv, i) ?? [])) {
252
+ datatypes += item.datatype === null ? 0 : 1;
253
+ }
254
+ }
255
+ return datatypes;
256
+ }
257
+ class ObographsExport {
258
+ /**
259
+ * Plan the export.
260
+ * @param snapshot - the snapshot
261
+ * @param settings - the resolved settings
262
+ */
263
+ constructor(snapshot, settings) {
264
+ this.snapshot = snapshot;
265
+ this.notes = [];
266
+ this.note = (code, message, column = null, count = null) => {
267
+ this.notes.push(Object.freeze({ code, message, column, count }));
268
+ };
269
+ /** IRI to the shorthand the importer names it by. */
270
+ this.shorthands = new Map();
271
+ /** Shorthand to the IRI of its property. */
272
+ this.shorthandIris = new Map();
273
+ /** The IRI written for each node. */
274
+ this.iris = [];
275
+ /** The nodes whose IRI reads back as another id. */
276
+ this.changedRows = new Set();
277
+ /** The Typedef nodes written with a shorthand, by node. */
278
+ this.typedefShorthands = new Map();
279
+ this.written = [];
280
+ this.rows = [];
281
+ this.frameless = new Uint8Array(0);
282
+ this.label = null;
283
+ this.placed = new Map();
284
+ this.properties = [];
285
+ this.metaColumn = null;
286
+ this.edgeColumns = [];
287
+ this.preds = new Map();
288
+ this.nonfinite = { count: 0 };
289
+ this.kept = keptOf(snapshot);
290
+ this.ontologyIri = ontologyIriOf(snapshot, this.kept, settings.ontologyIri);
291
+ this.indent = settings.indent !== "" ? `\n${settings.indent}` : "";
292
+ for (const [iri, entry] of Object.entries(this.kept.properties)) {
293
+ const shorthand = shorthandOf(entry.meta);
294
+ if (shorthand !== null) {
295
+ this.shorthands.set(iri, shorthand);
296
+ this.shorthandIris.set(shorthand, iri);
297
+ }
298
+ }
299
+ this.folding = pairFolding(snapshot);
300
+ this.ends = snapshot.edgeList();
301
+ for (let e = 0; e < snapshot.edgeCount; e++) {
302
+ if (!this.folding.folded(e)) {
303
+ this.written.push(e);
304
+ }
305
+ }
306
+ this.weights = explicitWeights(snapshot);
307
+ this.planIds();
308
+ this.planNodes();
309
+ this.fatal =
310
+ capabilityNotes(snapshot, settings.common, {
311
+ caps: dialectCapabilities("obographs"),
312
+ label: this.label,
313
+ labelAssumed: slotColumn(snapshot.nodes, "label", "name").assumed,
314
+ edgeSlot: "edge meta",
315
+ note: this.note,
316
+ }) ?? this.emptyIdError();
317
+ this.planColumnNotes();
318
+ this.planEdges(settings.common);
319
+ emptyColumnNotes(snapshot, this.rows, this.frameless, this.written, this.note);
320
+ // a dry run counts the non-finite numbers the document writes as null
321
+ if (this.fatal === null) {
322
+ const parts = this.write();
323
+ while (parts.next().done !== true) {
324
+ // only the counts the writing leaves behind are wanted
325
+ }
326
+ }
327
+ if (this.nonfinite.count > 0) {
328
+ this.note(NONFINITE_AS_NULL_CODE, `${this.nonfinite.count} NaN or infinite value${plural(this.nonfinite.count)} ${agree(this.nonfinite.count, "is", "are")} written as null`, null, this.nonfinite.count);
329
+ }
330
+ }
331
+ /**
332
+ * The id the importer reads an IRI back as: the shorthand of the property it names, else the
333
+ * compacted IRI.
334
+ * @param iri - the IRI
335
+ * @returns the id
336
+ */
337
+ reread(iri) {
338
+ return this.shorthands.get(iri) ?? compactOboIri(iri);
339
+ }
340
+ /**
341
+ * An id as an IRI: an IRI as it is, a CURIE as its OBO PURL, anything else under the
342
+ * ontology IRI.
343
+ * @param id - the id
344
+ * @returns the IRI
345
+ */
346
+ expand(id) {
347
+ if (IRI.test(id)) {
348
+ return id;
349
+ }
350
+ const curie = CURIE.exec(id);
351
+ if (curie !== null && !curie[1].includes("_")) {
352
+ return `${OBO_PURL}${curie[1]}_${curie[2]}`;
353
+ }
354
+ return `${this.ontologyIri}#${id}`;
355
+ }
356
+ /**
357
+ * The IRI to write for an id: the first form that reads back as the id (the property of a
358
+ * shorthand, the expanded IRI, the id itself); the id as it stands for a snapshot read with
359
+ * oboIds "iri".
360
+ * @param id - the id
361
+ * @returns the IRI and whether it reads back as the id
362
+ */
363
+ iriOf(id) {
364
+ const candidates = this.kept.ids === "iri"
365
+ ? [id]
366
+ : [this.shorthandIris.get(id), this.expand(id), id].filter((c) => c !== undefined);
367
+ const found = candidates.find((c) => this.reread(c) === id);
368
+ return found === undefined ? { iri: candidates[0], exact: false } : { iri: found, exact: true };
369
+ }
370
+ /**
371
+ * The pred to write for a relation: `is_a`, `type` for instance_of, the property of a
372
+ * shorthand, the expanded IRI or the relation itself, whichever reads back as the relation.
373
+ * @param r - the relation
374
+ * @returns the pred and whether it reads back as the relation
375
+ */
376
+ predOf(r) {
377
+ const reverse = REVERSE_PREDICATES[r];
378
+ const candidates = [reverse, this.shorthandIris.get(r), this.expand(r), r].filter((c) => c !== undefined && !PROPERTY_PREDICATES.has(c));
379
+ const reread = (c) => BUILTIN_PREDICATES[c] ?? this.shorthands.get(c) ?? compactOboIri(c);
380
+ const found = this.kept.ids === "iri"
381
+ ? candidates.find((c) => c === r && reread(c) === r)
382
+ : candidates.find((c) => reread(c) === r);
383
+ if (found !== undefined) {
384
+ return { pred: found, exact: true };
385
+ }
386
+ return { pred: this.kept.ids === "iri" ? r : candidates[0], exact: false };
387
+ }
388
+ /**
389
+ * An empty node id: OBO Graphs gives every node a non-empty id, and the importer skips a node
390
+ * without one, so the export is refused.
391
+ * @returns the error, or null when every id has text
392
+ */
393
+ emptyIdError() {
394
+ const { snapshot } = this;
395
+ let count = 0;
396
+ let first = -1;
397
+ for (let i = 0; i < snapshot.nodeCount; i++) {
398
+ if (String(snapshot.ids.idOf(i)) === "") {
399
+ count++;
400
+ first = first < 0 ? i : first;
401
+ }
402
+ }
403
+ if (count === 0) {
404
+ return null;
405
+ }
406
+ const message = `${count} node id${plural(count)} ${agree(count, "is", "are")} empty; an OBO Graphs node needs an id, so the save fails`;
407
+ this.note(LOSS.ID_CHARSET, message, null, count);
408
+ return new GraphFormatError("E_INVALID_ID", message, { reason: "charset", count, id: "", index: first });
409
+ }
410
+ /** The IRI of every node, the Typedefs named by a shorthand, and the numeric-id note. */
411
+ planIds() {
412
+ const { snapshot } = this;
413
+ const typeColumn = snapshot.nodes.get("type");
414
+ let numeric = 0;
415
+ for (let i = 0; i < snapshot.nodeCount; i++) {
416
+ const id = snapshot.ids.idOf(i);
417
+ numeric += typeof id === "number" ? 1 : 0;
418
+ const text = String(id);
419
+ let { iri, exact } = this.iriOf(text);
420
+ const typedef = typeColumn !== null && typeColumn.isSet(i) && typeColumn.value(i) === "Typedef";
421
+ if (!exact && typedef && !IRI.test(text) && this.kept.ids === "curie") {
422
+ // a Typedef named by its shorthand: written under an IRI with the shorthand declared
423
+ iri = this.expand(text);
424
+ this.shorthands.set(iri, text);
425
+ this.shorthandIris.set(text, iri);
426
+ this.typedefShorthands.set(i, text);
427
+ exact = true;
428
+ }
429
+ this.iris.push(iri);
430
+ if (!exact) {
431
+ this.changedRows.add(i);
432
+ }
433
+ }
434
+ if (numeric > 0) {
435
+ this.note(LOSS.ID_TEXT_TYPE, `${numeric} numeric node id${plural(numeric)} ${agree(numeric, "is", "are")} written as text and read back as strings`, null, numeric);
436
+ }
437
+ }
438
+ /** The written nodes (placeholders aside), the node order, and the columns with a place. */
439
+ planNodes() {
440
+ const { snapshot } = this;
441
+ const { src, dst } = this.ends;
442
+ this.frameless = framelessNodes(snapshot, this.written, {
443
+ outgoingAllowed: true,
444
+ changed: (i) => this.changedRows.has(i),
445
+ });
446
+ const moved = movedNodes(this.frameless, this.written.flatMap((e) => [src[e], dst[e]]));
447
+ if (moved > 0) {
448
+ this.note(NODE_ORDER_CODE, `${moved} node${plural(moved)} ${agree(moved, "reads", "read")} back at another position: placeholder nodes are not written and read back after the written nodes`, null, moved);
449
+ }
450
+ this.rows = [];
451
+ for (let i = 0; i < snapshot.nodeCount; i++) {
452
+ if (this.frameless[i] === 0) {
453
+ this.rows.push(i);
454
+ }
455
+ }
456
+ this.label = slotColumn(snapshot.nodes, "label", "name").column;
457
+ this.placeColumns();
458
+ this.planProperties();
459
+ }
460
+ /** The node columns written in their own places of a node (def, synonyms, xrefs...), not as property values. */
461
+ placeColumns() {
462
+ const { snapshot } = this;
463
+ const reproducible = (id) => typeof id === "string" && this.iriOf(id).exact;
464
+ for (const name of PLACED) {
465
+ const column = snapshot.nodes.get(name);
466
+ if (column !== null &&
467
+ column !== this.label &&
468
+ column.meta.role === null &&
469
+ carries(name, column, this.rows, reproducible)) {
470
+ this.placed.set(name, column);
471
+ }
472
+ }
473
+ const def = this.placed.get("def");
474
+ const defXrefs = this.placed.get("def.xrefs");
475
+ if (defXrefs !== undefined &&
476
+ (def === undefined || this.rows.some((i) => def.isSet(i) !== defXrefs.isSet(i)))) {
477
+ this.placed.delete("def.xrefs");
478
+ }
479
+ if (def !== undefined && !this.placed.has("def.xrefs") && snapshot.nodes.get("def.xrefs") !== null) {
480
+ this.placed.delete("def");
481
+ }
482
+ }
483
+ /** The node columns written as property values, each with its note. */
484
+ planProperties() {
485
+ const { snapshot } = this;
486
+ const slotted = new Set([...this.placed.values(), ...(this.label === null ? [] : [this.label])]);
487
+ for (const column of snapshot.nodes) {
488
+ const { role, name } = column.meta;
489
+ if (slotted.has(column) || (role !== null && UNWRITTEN_ROLES.has(role))) {
490
+ continue;
491
+ }
492
+ if (name === PLACEHOLDER_COLUMN && this.rows.every((i) => !column.isSet(i))) {
493
+ continue;
494
+ }
495
+ this.properties.push(column);
496
+ notePropertyColumn(this.note, column, this.rows, `basicPropertyValues (pred ${JSON.stringify(name)})`);
497
+ }
498
+ }
499
+ /** The notes about node and graph columns: Typedef nodes, dtypes, datatypes, graph columns. */
500
+ planColumnNotes() {
501
+ const { snapshot, rows, label, note } = this;
502
+ const type = this.placed.get("type");
503
+ const typedefs = type === undefined ? 0 : rows.filter((i) => type.isSet(i) && type.value(i) === "Typedef").length;
504
+ if (typedefs > 0) {
505
+ note(TYPEDEF_NODES_CODE, `${typedefs} node${plural(typedefs)} ${agree(typedefs, "is", "are")} written as PROPERTY nodes; they read back as nodes only when imported with typedefs: "nodes", and then their edges with them`, "type", typedefs);
506
+ }
507
+ for (const [name, column] of [...this.placed, ...(label === null ? [] : [["name", label]])]) {
508
+ dtypeNote(note, name === "name" ? "string" : OBO_NODE_COLUMNS[name].dtype, column);
509
+ }
510
+ const pv = this.placed.get("property_value");
511
+ const datatypes = pv === undefined ? 0 : countDatatypes(pv, rows);
512
+ if (datatypes > 0) {
513
+ note(OBOGRAPHS_LOSS.DATATYPE_DROPPED, `${datatypes} property value${plural(datatypes)} ${agree(datatypes, "carries", "carry")} an xsd datatype; OBO Graphs basicPropertyValues have none, so they read back without it`, "property_value", datatypes);
514
+ }
515
+ for (const column of snapshot.graph) {
516
+ note(GRAPH_COLUMN_AS_METADATA_CODE, `graph column "${column.meta.name}" is written as a basicPropertyValue of the graph's meta and reads back in meta.extra.obographs, not as a column`, column.meta.name, column.length - column.nullCount);
517
+ }
518
+ }
519
+ /**
520
+ * The edges' preds, meta and other columns, and their notes (relation, direction, ids that
521
+ * change).
522
+ * @param common - the common options
523
+ */
524
+ planEdges(common) {
525
+ const { snapshot, written, note } = this;
526
+ const slot = slotColumn(snapshot.edges, "kind", "relation");
527
+ const relation = slot.column;
528
+ if (slot.assumed && relation !== null) {
529
+ note(LOSS.ROLE_ASSUMED, `edge column "relation" has no role, so it is taken as the relation of each edge: it is written as each edge's pred, and reads back with the relation role ("kind")`, "relation", relation.length - relation.nullCount);
530
+ }
531
+ const meta = snapshot.edges.get("meta");
532
+ const metaOk = meta !== null &&
533
+ meta.dtype === "json" &&
534
+ meta.meta.role === null &&
535
+ written.every((e) => !meta.isSet(e) || isJsonObject(cellOf(meta, e)));
536
+ this.metaColumn = metaOk ? meta : null;
537
+ for (const column of snapshot.edges) {
538
+ const { role } = column.meta;
539
+ if (column === relation ||
540
+ column === this.metaColumn ||
541
+ role === "id" ||
542
+ (role !== null && UNWRITTEN_ROLES.has(role))) {
543
+ continue;
544
+ }
545
+ this.edgeColumns.push(column);
546
+ const count = written.filter((e) => column.isSet(e)).length;
547
+ if (count > 0) {
548
+ note(OBOGRAPHS_LOSS.EDGE_COLUMN_AS_META, `edge column "${column.meta.name}" is written into each edge's meta and reads back inside the meta column`, column.meta.name, count);
549
+ }
550
+ }
551
+ const { weights } = this;
552
+ const weighted = weights.weighted ? written.filter((e) => weights.isExplicit(e)).length : 0;
553
+ if (weighted > 0) {
554
+ note(OBOGRAPHS_LOSS.EDGE_COLUMN_AS_META, `${weighted} explicit edge weight${plural(weighted)} ${agree(weighted, "is", "are")} written as "weight" in each edge's meta and read back inside the meta column, not as weights`, snapshot.edges.byRole("weight")?.meta.name ?? null, weighted);
555
+ }
556
+ this.planPreds(relation);
557
+ this.directionNotes(common);
558
+ }
559
+ /**
560
+ * The pred of every written edge, with the relation and id notes.
561
+ * @param relation - the relation column, or null
562
+ */
563
+ planPreds(relation) {
564
+ let assumed = 0;
565
+ let relationChanges = 0;
566
+ for (const e of this.written) {
567
+ const value = relation === null ? undefined : cellOf(relation, e);
568
+ if (typeof value !== "string") {
569
+ assumed++;
570
+ this.preds.set(e, "is_a");
571
+ continue;
572
+ }
573
+ const { pred, exact } = this.predOf(value);
574
+ this.preds.set(e, pred);
575
+ relationChanges += exact ? 0 : 1;
576
+ }
577
+ if (assumed > 0) {
578
+ this.note(RELATION_ASSUMED_CODE, `${assumed} edge${plural(assumed)} ${agree(assumed, "has", "have")} no relation; written with the pred is_a (an ontology reads is_a as subclassing)`, relation?.meta.name ?? null, assumed);
579
+ }
580
+ const idChanges = this.rows.filter((i) => this.changedRows.has(i)).length;
581
+ if (idChanges + relationChanges > 0) {
582
+ this.note(OBOGRAPHS_LOSS.ID_CHANGED, `${idChanges} node id${plural(idChanges)} and ${relationChanges} relation${plural(relationChanges)} are written as IRIs the importer reads back as other ids under its default oboIds "curie"`, null, idChanges + relationChanges);
583
+ }
584
+ }
585
+ /**
586
+ * The direction notes: every OBO Graphs edge is directed.
587
+ * @param common - the common options
588
+ */
589
+ directionNotes(common) {
590
+ const { snapshot, written, folding, note } = this;
591
+ if (!snapshot.directed) {
592
+ note(DIRECTION_DROPPED_CODE, `the snapshot is undirected; OBO Graphs edges are directed and read back directed (${written.length} edge${plural(written.length)})`, null, written.length);
593
+ }
594
+ else if (common.onMixedDirection !== "error") {
595
+ const undirected = written.filter((e) => !folding.sourceDirected(e)).length;
596
+ if (undirected > 0) {
597
+ note(DIRECTION_DROPPED_CODE, `${undirected} undirected edge${plural(undirected)} ${agree(undirected, "is", "are")} written as one directed edge each`, null, undirected);
598
+ }
599
+ }
600
+ if (folding.mutualCount > 0) {
601
+ note(LOSS.MUTUAL_EXPANDED, `${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, "is", "are")} written as two edges; the mutual mark is lost`, null, folding.mutualCount);
602
+ }
603
+ }
604
+ /**
605
+ * A placed column's cell.
606
+ * @param name - the vocabulary name
607
+ * @param i - the node
608
+ * @returns the value, or undefined
609
+ */
610
+ at(name, i) {
611
+ const column = this.placed.get(name);
612
+ return column === undefined ? undefined : cellOf(column, i);
613
+ }
614
+ /**
615
+ * One node record as JSON.
616
+ * @param i - the node
617
+ * @returns the JSON text
618
+ */
619
+ nodeRecord(i) {
620
+ const node = { id: this.iris[i] };
621
+ const lbl = this.label === null ? undefined : cellOf(this.label, i);
622
+ if (typeof lbl === "string") {
623
+ node.lbl = lbl;
624
+ }
625
+ // without a type column every node is a class; the type also marks the document as OBO Graphs
626
+ const untyped = this.snapshot.nodes.get("type") === null ? "Term" : undefined;
627
+ const type = this.placed.has("type") ? this.at("type", i) : untyped;
628
+ if (typeof type === "string") {
629
+ node.type = NODE_TYPES[type] ?? type;
630
+ }
631
+ const propertyType = this.at("propertyType", i);
632
+ if (propertyType !== undefined) {
633
+ node.propertyType = propertyType;
634
+ }
635
+ const meta = this.nodeMeta(i);
636
+ const extra = this.at("obo.unrecognized", i);
637
+ if (isJsonObject(extra)) {
638
+ for (const [key, value] of Object.entries(extra)) {
639
+ if (key.startsWith("meta.")) {
640
+ meta[key.slice(5)] = value;
641
+ }
642
+ else {
643
+ node[key] = value;
644
+ }
645
+ }
646
+ }
647
+ if (Object.keys(meta).length > 0) {
648
+ node.meta = meta;
649
+ }
650
+ return json(node, this.nonfinite);
651
+ }
652
+ /**
653
+ * One node's meta: definition, comments, subsets, xrefs, synonyms, deprecated and the
654
+ * basicPropertyValues.
655
+ * @param i - the node
656
+ * @returns the meta record
657
+ */
658
+ nodeMeta(i) {
659
+ const meta = {};
660
+ const def = this.at("def", i);
661
+ if (typeof def === "string") {
662
+ meta.definition = { val: def, xrefs: this.at("def.xrefs", i) ?? [] };
663
+ }
664
+ const comment = this.at("comment", i);
665
+ if (typeof comment === "string") {
666
+ meta.comments = [comment];
667
+ }
668
+ const subsets = this.at("subset", i);
669
+ if (Array.isArray(subsets)) {
670
+ meta.subsets = subsets.map((s) => this.iriOf(String(s)).iri);
671
+ }
672
+ const xrefs = this.at("xref", i);
673
+ if (Array.isArray(xrefs)) {
674
+ meta.xrefs = xrefs.map((val) => ({ val }));
675
+ }
676
+ const synonyms = this.at("synonym", i);
677
+ if (Array.isArray(synonyms)) {
678
+ meta.synonyms = synonyms.map((s) => this.synonymRecord(s));
679
+ }
680
+ const obsolete = this.at("is_obsolete", i);
681
+ if (typeof obsolete === "boolean") {
682
+ meta.deprecated = obsolete;
683
+ }
684
+ const values = this.propertyValues(i);
685
+ if (values.length > 0) {
686
+ meta.basicPropertyValues = values;
687
+ }
688
+ return meta;
689
+ }
690
+ /**
691
+ * One synonym record.
692
+ * @param s - the synonym
693
+ * @returns the record
694
+ */
695
+ synonymRecord(s) {
696
+ const out = {
697
+ pred: s.scope === null ? "hasSynonym" : `has${s.scope[0]}${s.scope.slice(1).toLowerCase()}Synonym`,
698
+ };
699
+ if (s.text !== null) {
700
+ out.val = s.text;
701
+ }
702
+ if (s.xrefs.length > 0) {
703
+ out.xrefs = s.xrefs;
704
+ }
705
+ if (s.type !== null) {
706
+ out.synonymType = this.iriOf(s.type).iri;
707
+ }
708
+ if (s.meta !== undefined) {
709
+ out.meta = s.meta;
710
+ }
711
+ return out;
712
+ }
713
+ /**
714
+ * One node's basicPropertyValues: the tags OBO Graphs writes as annotations, the Typedef
715
+ * shorthand, the property values, then the columns outside the vocabulary.
716
+ * @param i - the node
717
+ * @returns the records
718
+ */
719
+ propertyValues(i) {
720
+ const values = [];
721
+ for (const tag of PROPERTY_TAGS) {
722
+ const v = this.at(tag, i);
723
+ const pred = TAG_PREDICATES.get(tag) ?? tag;
724
+ for (const item of valuesOf(v)) {
725
+ const text = String(item);
726
+ values.push({ pred, val: tag === "replaced_by" || tag === "consider" ? this.iriOf(text).iri : text });
727
+ }
728
+ }
729
+ const shorthand = this.typedefShorthands.get(i);
730
+ if (shorthand !== undefined) {
731
+ values.push({ pred: `${OBO_IN_OWL}shorthand`, val: shorthand });
732
+ }
733
+ for (const item of (this.at("property_value", i) ?? [])) {
734
+ values.push({ pred: this.iriOf(item.relation).iri, val: item.value });
735
+ }
736
+ for (const column of this.properties) {
737
+ for (const val of propertyTexts(column, i)) {
738
+ values.push({ pred: column.meta.name, val });
739
+ }
740
+ }
741
+ return values;
742
+ }
743
+ /**
744
+ * One edge record as JSON.
745
+ * @param e - the edge
746
+ * @returns the JSON text
747
+ */
748
+ edgeRecord(e) {
749
+ const { src, dst } = this.ends;
750
+ const edge = {
751
+ sub: this.iris[src[e]],
752
+ pred: this.preds.get(e),
753
+ obj: this.iris[dst[e]],
754
+ };
755
+ const base = this.metaColumn === null ? undefined : cellOf(this.metaColumn, e);
756
+ const meta = isJsonObject(base) ? { ...base } : {};
757
+ for (const column of this.edgeColumns) {
758
+ const v = cellOf(column, e);
759
+ if (v !== undefined) {
760
+ meta[column.meta.name] = v;
761
+ }
762
+ }
763
+ if (this.weights.weighted && this.weights.isExplicit(e)) {
764
+ meta.weight = this.weights.value(e);
765
+ }
766
+ if (Object.keys(meta).length > 0 || base !== undefined) {
767
+ edge.meta = meta;
768
+ }
769
+ return json(edge, this.nonfinite);
770
+ }
771
+ /**
772
+ * The graph record up to its nodes: the id, the label and the meta (the graph columns as
773
+ * basicPropertyValues).
774
+ * @returns the JSON text without its closing brace
775
+ */
776
+ graphHead() {
777
+ const { kept, snapshot } = this;
778
+ const graph = {
779
+ id: typeof kept.graph.id === "string" ? kept.graph.id : this.ontologyIri,
780
+ };
781
+ const named = snapshot.meta.name !== null && kept.graph.id === undefined;
782
+ const lbl = kept.graph.lbl ?? (named ? snapshot.meta.name : undefined);
783
+ if (lbl !== undefined) {
784
+ graph.lbl = lbl;
785
+ }
786
+ const meta = isJsonObject(kept.graph.meta) ? { ...kept.graph.meta } : {};
787
+ const values = Array.isArray(meta.basicPropertyValues)
788
+ ? [...meta.basicPropertyValues]
789
+ : [];
790
+ values.push(...graphPropertyValues(snapshot));
791
+ if (values.length > 0) {
792
+ meta.basicPropertyValues = values;
793
+ }
794
+ if (Object.keys(meta).length > 0) {
795
+ graph.meta = meta;
796
+ }
797
+ return json(graph, this.nonfinite).slice(0, -1);
798
+ }
799
+ /**
800
+ * The graph keys after the edges (the kept axioms and other keys).
801
+ * @returns the JSON text from the comma to the closing brace
802
+ */
803
+ graphTail() {
804
+ const rest = {};
805
+ for (const [key, value] of Object.entries(this.kept.graph)) {
806
+ if (key !== "id" && key !== "lbl" && key !== "meta" && key !== "nodes" && key !== "edges") {
807
+ rest[key] = value;
808
+ }
809
+ }
810
+ const text = json(rest, this.nonfinite);
811
+ return text === "{}" ? "}" : `,${text.slice(1)}`;
812
+ }
813
+ /**
814
+ * The kept PROPERTY nodes no written node stands for.
815
+ * @returns their JSON texts
816
+ */
817
+ propertyNodes() {
818
+ const writtenIris = new Set(this.rows.map((i) => this.iris[i]));
819
+ const out = [];
820
+ for (const [iri, entry] of Object.entries(this.kept.properties)) {
821
+ if (writtenIris.has(iri)) {
822
+ continue;
823
+ }
824
+ const node = { id: iri, lbl: entry.lbl, type: "PROPERTY" };
825
+ node.propertyType = entry.propertyType;
826
+ node.meta = entry.meta;
827
+ out.push(json(node, this.nonfinite));
828
+ }
829
+ return out;
830
+ }
831
+ /**
832
+ * The document's text parts.
833
+ * @yields the graph head, one part per node and edge, the tail
834
+ * @returns nothing
835
+ */
836
+ *write() {
837
+ if (this.fatal !== null) {
838
+ throw this.fatal;
839
+ }
840
+ const { indent } = this;
841
+ yield `{"graphs":[${this.graphHead()},"nodes":[`;
842
+ let first = true;
843
+ const item = (text) => {
844
+ const out = `${first ? "" : ","}${indent}${text}`;
845
+ first = false;
846
+ return out;
847
+ };
848
+ for (const i of this.rows) {
849
+ yield item(this.nodeRecord(i));
850
+ }
851
+ for (const node of this.propertyNodes()) {
852
+ yield item(node);
853
+ }
854
+ yield `],"edges":[`;
855
+ first = true;
856
+ for (const e of this.written) {
857
+ yield item(this.edgeRecord(e));
858
+ }
859
+ for (const edge of this.kept.propertyEdges) {
860
+ yield item(json(edge, this.nonfinite));
861
+ }
862
+ yield `]${this.graphTail()}]`;
863
+ const document = json(this.kept.document, this.nonfinite);
864
+ yield document === "{}" ? "}\n" : `,${document.slice(1)}\n`;
865
+ }
866
+ }
867
+ /**
868
+ * Plan an OBO Graphs export.
869
+ * @param snapshot - the snapshot
870
+ * @param settings - the resolved settings
871
+ * @returns the notes and the writer
872
+ * @category Plugin helpers
873
+ */
874
+ export function planObographs(snapshot, settings) {
875
+ const plan = new ObographsExport(snapshot, settings);
876
+ return { notes: plan.notes, write: () => plan.write() };
877
+ }
878
+ /**
879
+ * Whether a vocabulary column is written into its OBO Graphs place and read back unchanged on
880
+ * every written node.
881
+ * @param name - the column name (a PLACED name)
882
+ * @param column - the column
883
+ * @param rows - the written nodes
884
+ * @param reproducible - whether an id is written as an IRI that reads back as itself
885
+ * @returns true when the place carries the column
886
+ */
887
+ function carries(name, column, rows, reproducible) {
888
+ const spec = OBO_NODE_COLUMNS[name];
889
+ if (!fitsVocabulary(spec.dtype, column) || column.meta.components > 1) {
890
+ return false;
891
+ }
892
+ const valid = (v) => {
893
+ switch (name) {
894
+ case "type":
895
+ return typeof v === "string" && !Object.hasOwn(FRAME_TYPES, v);
896
+ case "propertyType":
897
+ case "def":
898
+ case "comment":
899
+ case "namespace":
900
+ case "created_by":
901
+ case "creation_date":
902
+ return typeof v === "string";
903
+ case "is_obsolete":
904
+ return typeof v === "boolean";
905
+ case "def.xrefs":
906
+ return strings(v, true);
907
+ case "xref":
908
+ case "alt_id":
909
+ return strings(v);
910
+ case "subset":
911
+ case "replaced_by":
912
+ case "consider":
913
+ return strings(v) && v.every(reproducible);
914
+ case "synonym":
915
+ return (Array.isArray(v) &&
916
+ v.length > 0 &&
917
+ v.every((s) => isJsonObject(s) &&
918
+ Object.keys(s).length === ("meta" in s ? 5 : 4) &&
919
+ (s.text === null || typeof s.text === "string") &&
920
+ (s.scope === null || (typeof s.scope === "string" && SYNONYM_SCOPES.has(s.scope))) &&
921
+ (s.type === null || reproducible(s.type)) &&
922
+ strings(s.xrefs, true)));
923
+ case "property_value":
924
+ return (Array.isArray(v) &&
925
+ v.length > 0 &&
926
+ v.every((x) => isJsonObject(x) &&
927
+ Object.keys(x).length === 3 &&
928
+ reproducible(x.relation) &&
929
+ !OBOGRAPHS_PREDICATE_TAGS.has(String(x.relation)) &&
930
+ typeof x.value === "string" &&
931
+ (x.datatype === null || typeof x.datatype === "string")));
932
+ case "obo.unrecognized":
933
+ return (isJsonObject(v) &&
934
+ Object.keys(v).every((key) => key.startsWith("meta.") ? !META_KEYS.has(key.slice(5)) && key.length > 5 : !NODE_KEYS.has(key)));
935
+ default:
936
+ return false;
937
+ }
938
+ };
939
+ return rows.every((i) => !column.isSet(i) || valid(cellOf(column, i)));
940
+ }
941
+ //# sourceMappingURL=obographs-export.js.map