@graphty/graph-io 0.3.25 → 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
@@ -1,6 +1,7 @@
1
1
  /**
2
- * The `@graphty/graph-io/graphml` subpath: the GraphML importer and exporter (design section 8.2),
2
+ * The `@graphty/graph-io/graphml` subpath: the GraphML importer and exporter,
3
3
  * their option types and their issue and loss-note code tables.
4
+ * @module @graphty/graph-io/graphml
4
5
  */
5
6
 
6
7
  export { GRAPHML_ISSUE, GRAPHML_LOSS } from "./constants.js";
@@ -39,6 +39,7 @@ interface Frame {
39
39
  * Builds the tree of one subtree from start / end / text events. The outermost frame is the
40
40
  * `<data>` element itself; `finish()` returns its content: the object of its children, or its
41
41
  * text when it has none.
42
+ * @category Plugin helpers
42
43
  */
43
44
  export class XmlTreeBuilder {
44
45
  private readonly frames: Frame[] = [];
@@ -151,20 +152,22 @@ function attachChild(parent: Frame, name: string, value: unknown): void {
151
152
  }
152
153
 
153
154
  /**
154
- * Whether a value is a tree the writer can serialise: a string, number, boolean or null (text),
155
+ * Whether a value is a tree the writer can serialize: a string, number, boolean or null (text),
155
156
  * an array of such trees, or an object whose keys are `#text`, `@_<Name>` or `<Name>` with tree
156
157
  * values.
157
158
  * @param value - the value
158
159
  * @returns true when writeXmlTree() accepts it
160
+ * @category Plugin helpers
159
161
  */
160
162
  export function isXmlTree(value: unknown): boolean {
161
163
  return treeProblem(value) === null;
162
164
  }
163
165
 
164
166
  /**
165
- * Why a value is not a serialisable tree.
167
+ * Why a value is not a serializable tree.
166
168
  * @param value - the value
167
169
  * @returns a message, or null when the value is a tree
170
+ * @category Plugin helpers
168
171
  */
169
172
  export function treeProblem(value: unknown): string | null {
170
173
  if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
@@ -220,6 +223,7 @@ export function treeProblem(value: unknown): string | null {
220
223
  * @param value - the tree (the content of a `<data>` element)
221
224
  * @param indent - the indentation of the containing element's children
222
225
  * @param out - receives the text parts
226
+ * @category Plugin helpers
223
227
  */
224
228
  export function writeXmlTree(value: unknown, indent: string, out: string[]): void {
225
229
  const problem = treeProblem(value);
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * yFiles / yEd graphics read out of the JSON tree of a `yfiles.type` key (tree.ts) into typed
3
3
  * columns, beside the tree itself: a `y:ShapeNode` gives the node's position, size, fill and
4
- * border colours, label and shape, and a `y:PolyLineEdge` gives the edge's line colour and width,
4
+ * border colors, label and shape, and a `y:PolyLineEdge` gives the edge's line color and width,
5
5
  * its arrows and the direction they draw. The values are the ones graphty-element's own GraphML
6
- * parser produced, so a consumer rebuilds its records by dropping the `yfiles.` prefix: colours
6
+ * parser produced, so a consumer rebuilds its records by dropping the `yfiles.` prefix: colors
7
7
  * are `#RRGGBB` in upper case (a `#RGB` is expanded, any other text is kept as written), numbers
8
8
  * are parsed with parseFloat, the position is `[x, y, 0]` and the shape is the yFiles shape type
9
9
  * as written. One difference: a label whose text is a number (`<y:NodeLabel>0</y:NodeLabel>`) is
@@ -52,6 +52,7 @@ const EDGE_FIELDS: Readonly<Record<string, Omit<ColumnDecl, "name">>> = {
52
52
  * @param field - the field name (a key of the values graphicsValues() returns)
53
53
  * @param keyId - the id of the GraphML key whose tree it is read from
54
54
  * @returns the declaration
55
+ * @category Plugin helpers
55
56
  */
56
57
  export function graphicsDecl(domain: "node" | "edge", field: string, keyId: string): ColumnDecl {
57
58
  const fields = domain === "node" ? NODE_FIELDS : EDGE_FIELDS;
@@ -76,6 +77,7 @@ export function graphicsDecl(domain: "node" | "edge", field: string, keyId: stri
76
77
  * @param meta.dtype - the column dtype
77
78
  * @param meta.origin - the column origin
78
79
  * @returns true for a mapped graphics column
80
+ * @category Plugin helpers
79
81
  */
80
82
  export function isGraphicsColumn(meta: {
81
83
  readonly name: string;
@@ -95,6 +97,7 @@ export function isGraphicsColumn(meta: {
95
97
  * @param table - the table it is in
96
98
  * @param domain - node or edge
97
99
  * @returns the number of rows that differ from the trees
100
+ * @category Plugin helpers
98
101
  */
99
102
  export function staleGraphicsRows(column: Column, table: Iterable<Column>, domain: "node" | "edge"): number {
100
103
  const field = column.meta.name.slice(YFILES_COLUMN_PREFIX.length);
@@ -130,19 +133,21 @@ export function staleGraphicsRows(column: Column, table: Iterable<Column>, domai
130
133
  * PolyLineEdge's for an edge; nothing for any other graphics (GenericNode, BezierEdge, ...).
131
134
  * @param domain - node or edge
132
135
  * @param tree - the `<data>` content as tree.ts builds it
136
+ * @param unmapped - receives the fields whose text is present but not a number (not mapped)
133
137
  * @returns field name -> value, in declaration order
138
+ * @category Plugin helpers
134
139
  */
135
- export function graphicsValues(domain: "node" | "edge", tree: unknown): [string, unknown][] {
140
+ export function graphicsValues(domain: "node" | "edge", tree: unknown, unmapped: string[] = []): [string, unknown][] {
136
141
  const out: [string, unknown][] = [];
137
142
  if (domain === "node") {
138
143
  const shape = child(tree, "ShapeNode");
139
144
  if (shape !== undefined) {
140
- shapeNodeValues(shape, out);
145
+ shapeNodeValues(shape, out, unmapped);
141
146
  }
142
147
  } else {
143
148
  const edge = child(tree, "PolyLineEdge");
144
149
  if (edge !== undefined) {
145
- polyLineEdgeValues(edge, out);
150
+ polyLineEdgeValues(edge, out, unmapped);
146
151
  }
147
152
  }
148
153
  return out;
@@ -152,21 +157,22 @@ export function graphicsValues(domain: "node" | "edge", tree: unknown): [string,
152
157
  * Read a ShapeNode.
153
158
  * @param shape - the ShapeNode element
154
159
  * @param out - receives the values
160
+ * @param unmapped - receives the fields whose text is not a number
155
161
  */
156
- function shapeNodeValues(shape: unknown, out: [string, unknown][]): void {
162
+ function shapeNodeValues(shape: unknown, out: [string, unknown][], unmapped: string[]): void {
157
163
  const geometry = child(shape, "Geometry");
158
164
  // yFiles requires x, y, width and height on Geometry; a position needs both coordinates
159
- const x = number(attr(geometry, "x"));
160
- const y = number(attr(geometry, "y"));
165
+ const x = checked(attr(geometry, "x"), "x", unmapped);
166
+ const y = checked(attr(geometry, "y"), "y", unmapped);
161
167
  if (x !== undefined && y !== undefined) {
162
168
  out.push(["position", [x, y, 0]]);
163
169
  }
164
- push(out, "width", number(attr(geometry, "width")));
165
- push(out, "height", number(attr(geometry, "height")));
170
+ push(out, "width", checked(attr(geometry, "width"), "width", unmapped));
171
+ push(out, "height", checked(attr(geometry, "height"), "height", unmapped));
166
172
  push(out, "color", color(attr(child(shape, "Fill"), "color")));
167
173
  const border = child(shape, "BorderStyle");
168
174
  push(out, "borderColor", color(attr(border, "color")));
169
- push(out, "borderWidth", number(attr(border, "width")));
175
+ push(out, "borderWidth", checked(attr(border, "width"), "borderWidth", unmapped));
170
176
  const label = child(shape, "NodeLabel");
171
177
  // an element with no text and no attributes is "" (no label); one with attributes but no text is a blank label
172
178
  if (typeof label === "string" ? label.length > 0 : label !== undefined) {
@@ -180,11 +186,12 @@ function shapeNodeValues(shape: unknown, out: [string, unknown][]): void {
180
186
  * Read a PolyLineEdge.
181
187
  * @param edge - the PolyLineEdge element
182
188
  * @param out - receives the values
189
+ * @param unmapped - receives the fields whose text is not a number
183
190
  */
184
- function polyLineEdgeValues(edge: unknown, out: [string, unknown][]): void {
191
+ function polyLineEdgeValues(edge: unknown, out: [string, unknown][], unmapped: string[]): void {
185
192
  const line = child(edge, "LineStyle");
186
193
  push(out, "color", color(attr(line, "color")));
187
- push(out, "width", number(attr(line, "width")));
194
+ push(out, "width", checked(attr(line, "width"), "width", unmapped));
188
195
  const arrows = child(edge, "Arrows");
189
196
  if (arrows !== undefined && typeof arrows === "object") {
190
197
  const target = attr(arrows, "target");
@@ -273,9 +280,24 @@ function number(value: string | undefined): number | undefined {
273
280
  }
274
281
 
275
282
  /**
276
- * A colour attribute: `#RRGGBB` upper-cased, `#RGB` expanded, anything else as written.
283
+ * A number attribute, recording a present text that is not a number.
277
284
  * @param value - the text
278
- * @returns the colour, or undefined when absent or empty
285
+ * @param field - the field it maps to
286
+ * @param unmapped - receives the field when the text is not a number
287
+ * @returns the number, or undefined
288
+ */
289
+ function checked(value: string | undefined, field: string, unmapped: string[]): number | undefined {
290
+ const n = number(value);
291
+ if (n === undefined && value !== undefined && value.length > 0) {
292
+ unmapped.push(field);
293
+ }
294
+ return n;
295
+ }
296
+
297
+ /**
298
+ * A color attribute: `#RRGGBB` upper-cased, `#RGB` expanded, anything else as written.
299
+ * @param value - the text
300
+ * @returns the color, or undefined when absent or empty
279
301
  */
280
302
  function color(value: string | undefined): string | undefined {
281
303
  if (value === undefined || value.length === 0) {
@@ -8,20 +8,27 @@
8
8
  * / `graph`), the d3 lineage of the same shape (`links`, `name` ids, integer index endpoints),
9
9
  * JSON Graph Format v2 (`graph.nodes` keyed by id, per-edge `directed`, hyperedges), Cytoscape.js
10
10
  * elements (`data.id` / `data.source` / `data.target`, `position`, `classes`, `data.parent`),
11
- * graphology serialisation (`key` / `attributes`, `undirected` edges, `options.type` / `multi`) and
11
+ * graphology serialization (`key` / `attributes`, `undirected` edges, `options.type` / `multi`) and
12
12
  * vis.js (`from` / `to`); read only: NetworkX adjacency_data (`nodes` + `adjacency`) and tree_data
13
13
  * (nested `id` / `children`).
14
14
  */
15
15
 
16
- import { type GraphMeta } from "@graphty/graph-format";
16
+ import { type GraphMeta, type GraphSnapshot } from "@graphty/graph-format";
17
17
 
18
18
  import { capabilities } from "../../common/export.js";
19
+ import { trimTrailingZeros } from "../../common/text.js";
19
20
  import { type ExportCapabilities } from "../../types.js";
20
21
 
21
- /** The JSON dialects the plugin reads and writes. */
22
- export type JsonDialect = "node-link" | "d3" | "jgf" | "cytoscape" | "graphology" | "vis";
22
+ /**
23
+ * The JSON dialects the plugin reads and writes.
24
+ * @category Built-in formats
25
+ */
26
+ export type JsonDialect = "node-link" | "d3" | "jgf" | "cytoscape" | "graphology" | "vis" | "obographs";
23
27
 
24
- /** Every dialect name, for option checking and messages. */
28
+ /**
29
+ * Every dialect name, for option checking and messages.
30
+ * @category Built-in formats
31
+ */
25
32
  export const JSON_DIALECTS: readonly JsonDialect[] = Object.freeze([
26
33
  "node-link",
27
34
  "d3",
@@ -29,31 +36,38 @@ export const JSON_DIALECTS: readonly JsonDialect[] = Object.freeze([
29
36
  "cytoscape",
30
37
  "graphology",
31
38
  "vis",
39
+ "obographs",
32
40
  ]);
33
41
 
34
42
  /**
35
- * The dialects the importer reads: every JsonDialect plus three it only reads, NetworkX
36
- * adjacency_data (`nodes` plus one neighbour list per node under `adjacency`), tree_data (a
37
- * nested `id` / `children` record) and OBO Graphs (`graphs[]` of `sub` / `pred` / `obj` edges, the
38
- * JSON form of the Gene Ontology and the OBO Foundry ontologies). The exporter writes none of them.
43
+ * The dialects the importer reads: every JsonDialect plus two it only reads, NetworkX
44
+ * adjacency_data (`nodes` plus one neighbor list per node under `adjacency`) and tree_data (a
45
+ * nested `id` / `children` record). The exporter writes neither.
46
+ * @category Built-in formats
39
47
  */
40
- export type JsonImportDialect = JsonDialect | "adjacency" | "tree" | "obographs";
48
+ export type JsonImportDialect = JsonDialect | "adjacency" | "tree";
41
49
 
42
- /** Every dialect the importer reads, for option checking and messages. */
50
+ /**
51
+ * Every dialect the importer reads, for option checking and messages.
52
+ * @category Plugin helpers
53
+ */
43
54
  export const JSON_IMPORT_DIALECTS: readonly JsonImportDialect[] = Object.freeze([
44
55
  ...JSON_DIALECTS,
45
56
  "adjacency",
46
57
  "tree",
47
- "obographs",
48
58
  ]);
49
59
 
50
- /** The key under `meta.extra` that holds the shape record (design section 8.5). */
60
+ /**
61
+ * The key under `meta.extra` that holds the shape record (design section 8.5).
62
+ * @category Plugin helpers
63
+ */
51
64
  export const META_KEY = "json";
52
65
 
53
66
  /**
54
67
  * The shape information the importer records under `meta.extra.json` so the exporter can write the
55
- * same file back (design section 8.5). Every field is optional because a snapshot may come from
56
- * another format or from an older record.
68
+ * same file back; `jsonShapeOf(snapshot)` reads it. Every field is optional because a graph may
69
+ * come from another format.
70
+ * @category Built-in formats
57
71
  */
58
72
  export interface JsonShapeMeta {
59
73
  /** The dialect the file was read as. */
@@ -78,10 +92,24 @@ export interface JsonShapeMeta {
78
92
  readonly cytoscape?: Readonly<Record<string, unknown>> | undefined;
79
93
  }
80
94
 
95
+ /**
96
+ * What a JSON import recorded about the document's shape: the dialect it was read as
97
+ * (`jsonShapeOf(snapshot)?.dialect`), the keys it used, and so on. A JSON export with default
98
+ * options writes the same shape back.
99
+ * @param snapshot - a graph read from a JSON document
100
+ * @returns the shape, or null for a graph that was not read from JSON
101
+ * @category Built-in formats
102
+ */
103
+ export function jsonShapeOf(snapshot: GraphSnapshot): JsonShapeMeta | null {
104
+ const shape = snapshot.meta.extra[META_KEY];
105
+ return isJsonObject(shape) ? (shape as JsonShapeMeta) : null;
106
+ }
107
+
81
108
  /**
82
109
  * Whether a value is a plain JSON object (not null, not an array).
83
110
  * @param value - any value
84
111
  * @returns true for an object that is not an array
112
+ * @category Plugin helpers
85
113
  */
86
114
  export function isJsonObject(value: unknown): value is Record<string, unknown> {
87
115
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -93,6 +121,7 @@ export function isJsonObject(value: unknown): value is Record<string, unknown> {
93
121
  * @param record - the record
94
122
  * @param key - the key
95
123
  * @returns true when the key is an own property
124
+ * @category Plugin helpers
96
125
  */
97
126
  export function hasKey(record: Readonly<Record<string, unknown>>, key: string): boolean {
98
127
  return Object.prototype.hasOwnProperty.call(record, key);
@@ -102,6 +131,7 @@ export function hasKey(record: Readonly<Record<string, unknown>>, key: string):
102
131
  * Whether a text names a dialect.
103
132
  * @param value - any value
104
133
  * @returns true for one of JSON_DIALECTS
134
+ * @category Plugin helpers
105
135
  */
106
136
  export function isJsonDialect(value: unknown): value is JsonDialect {
107
137
  return typeof value === "string" && (JSON_DIALECTS as readonly string[]).includes(value);
@@ -111,6 +141,7 @@ export function isJsonDialect(value: unknown): value is JsonDialect {
111
141
  * Whether a text names a dialect the importer reads.
112
142
  * @param value - any value
113
143
  * @returns true for one of JSON_IMPORT_DIALECTS
144
+ * @category Plugin helpers
114
145
  */
115
146
  export function isJsonImportDialect(value: unknown): value is JsonImportDialect {
116
147
  return typeof value === "string" && (JSON_IMPORT_DIALECTS as readonly string[]).includes(value);
@@ -121,13 +152,15 @@ export function isJsonImportDialect(value: unknown): value is JsonImportDialect
121
152
  * `elements` or a top-level array of `{ data }` elements; OBO Graphs: `graphs[]` whose first graph
122
153
  * has an edge with `sub` (or `subj`) and `obj` or a `pred`, or a node with `lbl`, `meta` or an OWL
123
154
  * `type`; JGF: `graph.nodes` / `graph.edges` or any other `graphs[]`; graphology: `options.type` / `options.multi`, `key` nodes without `id`, edges with
124
- * `undirected` or an `attributes` record; vis: edges with `from` / `to`; d3: `links` without
155
+ * `undirected` or an `attributes` record, and vis: edges with `from` / `to`, both only without
156
+ * NetworkX's `links` / `directed` / `multigraph` / `graph` keys; d3: `links` without
125
157
  * `directed` / `multigraph` / `graph`; NetworkX adjacency_data: `nodes` and `adjacency` without
126
158
  * `links` / `edges`; NetworkX tree_data: `children` without `nodes` / `links` / `edges`; else
127
159
  * node-link). Pure: the importer wraps it with its issue
128
160
  * codes, the registry's sniff() uses it on a head that parses as a whole document.
129
161
  * @param root - the parsed document
130
162
  * @returns the dialect, or null when the document is not a graph document in any dialect
163
+ * @category Plugin helpers
131
164
  */
132
165
  export function sniffJsonDialect(root: unknown): JsonImportDialect | null {
133
166
  if (Array.isArray(root)) {
@@ -144,7 +177,8 @@ export function sniffJsonDialect(root: unknown): JsonImportDialect | null {
144
177
  return "jgf";
145
178
  }
146
179
  if (Array.isArray(root.graphs)) {
147
- return isOboGraph(firstJsonObject(root.graphs)) ? "obographs" : "jgf";
180
+ // any graph decides: an ontology's first graph may be an empty stub before its imports
181
+ return root.graphs.some((g: unknown) => isJsonObject(g) && isOboGraph(g)) ? "obographs" : "jgf";
148
182
  }
149
183
  if (!hasKey(root, "edges") && !hasKey(root, "links")) {
150
184
  if (hasKey(root, "nodes") && hasKey(root, "adjacency")) {
@@ -159,15 +193,25 @@ export function sniffJsonDialect(root: unknown): JsonImportDialect | null {
159
193
  if (isJsonObject(root.options) && (hasKey(root.options, "type") || hasKey(root.options, "multi"))) {
160
194
  return "graphology";
161
195
  }
162
- if (firstNode !== null && hasKey(firstNode, "key") && !hasKey(firstNode, "id")) {
196
+ // NetworkX's own keys (links, directed, multigraph, graph) settle node-link: one attribute named
197
+ // like a graphology or vis field (`attributes`, `undirected`, `key`, `from`) must not re-route it
198
+ const networkx =
199
+ hasKey(root, "links") || hasKey(root, "directed") || hasKey(root, "multigraph") || hasKey(root, "graph");
200
+ if (!networkx && firstNode !== null && hasKey(firstNode, "key") && !hasKey(firstNode, "id")) {
163
201
  return "graphology";
164
202
  }
165
- if (firstEdge !== null && !hasKey(firstEdge, "from")) {
203
+ if (!networkx && firstEdge !== null && !hasKey(firstEdge, "from")) {
166
204
  if (hasKey(firstEdge, "undirected") || isJsonObject(firstEdge.attributes)) {
167
205
  return "graphology";
168
206
  }
169
207
  }
170
- if (firstEdge !== null && hasKey(firstEdge, "from") && hasKey(firstEdge, "to") && !hasKey(firstEdge, "source")) {
208
+ if (
209
+ !networkx &&
210
+ firstEdge !== null &&
211
+ hasKey(firstEdge, "from") &&
212
+ hasKey(firstEdge, "to") &&
213
+ !hasKey(firstEdge, "source")
214
+ ) {
171
215
  return "vis";
172
216
  }
173
217
  const bare = !hasKey(root, "directed") && !hasKey(root, "multigraph") && !hasKey(root, "graph");
@@ -217,6 +261,7 @@ function firstJsonObject(value: unknown): Record<string, unknown> | null {
217
261
  * from the JSON importer.
218
262
  * @param meta - the snapshot's metadata
219
263
  * @returns the fields found under `meta.extra.json`, each only when it has the expected type
264
+ * @category Plugin helpers
220
265
  */
221
266
  export function shapeMetaOf(meta: GraphMeta): JsonShapeMeta {
222
267
  const raw: unknown = meta.extra[META_KEY];
@@ -240,7 +285,10 @@ export function shapeMetaOf(meta: GraphMeta): JsonShapeMeta {
240
285
  };
241
286
  }
242
287
 
243
- /** The direction a dialect assumes when the file declares none (design section 8.4, `defaultDirected`). */
288
+ /**
289
+ * The direction a dialect assumes when the file declares none (design section 8.4, `defaultDirected`).
290
+ * @category Plugin helpers
291
+ */
244
292
  export const DIALECT_DEFAULT_DIRECTED: Readonly<Record<JsonImportDialect, boolean>> = Object.freeze({
245
293
  "node-link": false,
246
294
  d3: false,
@@ -322,10 +370,19 @@ const TABLES: Readonly<Record<JsonDialect, ExportCapabilities>> = Object.freeze(
322
370
  hierarchy: false,
323
371
  graphAttributes: false,
324
372
  }),
373
+ // the OBO flat file's table: no column of the snapshot's own reads back as a column (the
374
+ // vocabulary columns have their places; every other one becomes property values or edge meta)
375
+ obographs: capabilities({
376
+ mixedDirection: false,
377
+ multiEdges: true,
378
+ selfLoops: true,
379
+ edgeIds: "none",
380
+ idCharset: "any",
381
+ }),
325
382
  });
326
383
 
327
384
  /**
328
- * What one dialect can express (design section 8.5): positions and visual columns are written as
385
+ * What one dialect can express: positions and visual columns are written as
329
386
  * plain attributes (an array for a multi-component column) and read back without their role,
330
387
  * except Cytoscape's `position` object; containment only as the Cytoscape `data.parent`; mixed
331
388
  * direction only where the dialect carries a per-edge flag (JGF `directed`, graphology
@@ -333,12 +390,16 @@ const TABLES: Readonly<Record<JsonDialect, ExportCapabilities>> = Object.freeze(
333
390
  * graph attributes everywhere but d3 (the bare shape) and vis.
334
391
  * @param dialect - the dialect
335
392
  * @returns its frozen capability table
393
+ * @category Built-in formats
336
394
  */
337
395
  export function dialectCapabilities(dialect: JsonDialect): ExportCapabilities {
338
396
  return TABLES[dialect];
339
397
  }
340
398
 
341
- /** The Cytoscape element-level keys (everything else on an element lives under `data`). */
399
+ /**
400
+ * The Cytoscape element-level keys (everything else on an element lives under `data`).
401
+ * @category Plugin helpers
402
+ */
342
403
  export const CYTOSCAPE_ELEMENT_KEYS: ReadonlySet<string> = new Set([
343
404
  "selected",
344
405
  "selectable",
@@ -350,13 +411,17 @@ export const CYTOSCAPE_ELEMENT_KEYS: ReadonlySet<string> = new Set([
350
411
  "renderedPosition",
351
412
  ]);
352
413
 
353
- /** The Cytoscape element keys the importer maps structurally rather than to columns. */
414
+ /**
415
+ * The Cytoscape element keys the importer maps structurally rather than to columns.
416
+ * @category Plugin helpers
417
+ */
354
418
  export const CYTOSCAPE_STRUCTURAL_KEYS: ReadonlySet<string> = new Set(["data", "group", "position", "classes"]);
355
419
 
356
420
  /**
357
421
  * The suffix the importer appends to a column name that collides with a structural column or a
358
422
  * reserved key of its dialect (design section 5.6 names collisions deterministically); the exporter
359
423
  * strips it when the value goes back to the level the suffix names.
424
+ * @category Plugin helpers
360
425
  */
361
426
  export const SUFFIX = Object.freeze({
362
427
  /** A Cytoscape `data` key or a JGF / graphology attribute that collides with a structural column. */
@@ -365,17 +430,51 @@ export const SUFFIX = Object.freeze({
365
430
  element: "#element",
366
431
  });
367
432
 
368
- /** The default source keys of a node-link edge record, tried in order (as fromRecords does). */
433
+ /**
434
+ * The default source keys of a node-link edge record, tried in order (as fromRecords does).
435
+ * @category Plugin helpers
436
+ */
369
437
  export const NODE_LINK_SOURCE_KEYS: readonly string[] = Object.freeze(["source", "src", "from"]);
370
438
 
371
- /** The default target keys of a node-link edge record, tried in order. */
439
+ /**
440
+ * The default target keys of a node-link edge record, tried in order.
441
+ * @category Plugin helpers
442
+ */
372
443
  export const NODE_LINK_TARGET_KEYS: readonly string[] = Object.freeze(["target", "dst", "to"]);
373
444
 
374
- /** The name of the position column every JSON dialect writes / reads (design section 5.2). */
445
+ /**
446
+ * The name of the position column every JSON dialect writes / reads (design section 5.2).
447
+ * @category Plugin helpers
448
+ */
375
449
  export const POSITION_COLUMN = "position";
376
450
 
377
- /** The name of the Cytoscape classes column (a list of strings with role "classes"). */
451
+ /**
452
+ * The name of the Cytoscape classes column (a list of strings with role "classes").
453
+ * @category Plugin helpers
454
+ */
378
455
  export const CLASSES_COLUMN = "classes";
379
456
 
380
- /** The name of the Cytoscape parent column (u32 refersTo node, role "parent"). */
457
+ /**
458
+ * The name of the Cytoscape parent column (u32 refersTo node, role "parent").
459
+ * @category Plugin helpers
460
+ */
381
461
  export const PARENT_COLUMN = "parent";
462
+
463
+ /**
464
+ * An integer text beyond 2^53 in exponent form (`100000000000000000000` -> `1e+20`, the same
465
+ * digits): the importer reads an integer literal that large as its exact digits (a string), so
466
+ * a number must not be written as one.
467
+ * @param text - the shortest decimal text of a finite number
468
+ * @returns the text, or its exponent form for an integer literal of 16 or more digits
469
+ * @category Plugin helpers
470
+ */
471
+ export function exponentIfUnsafe(text: string): string {
472
+ const match = /^(-?)(\d{16,})$/.exec(text);
473
+ if (match === null || Number.isSafeInteger(Number(text))) {
474
+ return text;
475
+ }
476
+ const [, sign, digits] = match;
477
+ const mantissa = trimTrailingZeros(digits);
478
+ const fraction = mantissa.length > 1 ? `.${mantissa.slice(1)}` : "";
479
+ return `${sign}${mantissa[0]}${fraction}e+${digits.length - 1}`;
480
+ }