@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,432 @@
1
+ /**
2
+ * The exporter machinery CX version 1 and CX2 share (design/graph-io/cytoscape-and-obo/design.md
3
+ * sections 1.2 and 1.3): integer node ids (safe integers, or the digits of an integer beyond 2^53
4
+ * written raw), sanitizeIds "mangle" renumbering, edge ids from the id role column, the declared
5
+ * type of a column, the direction notes (every CX edge is directed) and the JSON writer that keeps
6
+ * -0 and raw big integers.
7
+ */
8
+
9
+ import { type Column, GraphFormatError, type GraphSnapshot, type NodeId } from "@graphty/graph-format";
10
+
11
+ import { type LossNote } from "../types.js";
12
+ import { type PairFolding } from "./direction.js";
13
+ import { LOSS } from "./export.js";
14
+ import { type ResolvedExportOptions } from "./options.js";
15
+ import { agree, plural } from "./plural.js";
16
+
17
+ /**
18
+ * Records a loss note.
19
+ * @category Plugin helpers
20
+ */
21
+ export type CxNoteFn = (code: string, message: string, column?: string | null, count?: number | null) => void;
22
+
23
+ /**
24
+ * The prefix of a string that stands for a raw number literal in the output: -0 (which
25
+ * JSON.stringify writes as 0) and an integer id beyond 2^53 (kept as its digits).
26
+ */
27
+ const RAW = `${String.fromCodePoint(0)}cx:`;
28
+
29
+ /** A raw literal as JSON.stringify writes it, to be unquoted. */
30
+ const RAW_JSON = /"\\u0000cx:(-?\d+)"/g;
31
+
32
+ /** An integer literal beyond 2^53 as text: a CX id graph-io keeps as its digits. */
33
+ const BIG_INTEGER_TEXT = /^-?[1-9]\d{15,}$/;
34
+
35
+ /**
36
+ * The node ids as written: the original, a renumbered one, or a raw big integer.
37
+ * @category Plugin helpers
38
+ */
39
+ export interface WrittenIds {
40
+ /** How many ids were renumbered (sanitizeIds "mangle"). */
41
+ readonly changed: number;
42
+ /**
43
+ * The written id of a node.
44
+ * @param i - the node index
45
+ * @returns a number, or a raw string for a big integer
46
+ */
47
+ idAt(i: number): NodeId;
48
+ /**
49
+ * Whether a node was renumbered.
50
+ * @param i - the node index
51
+ * @returns true when its original goes into graphty:originalId
52
+ */
53
+ isChanged(i: number): boolean;
54
+ /**
55
+ * The original id of a node.
56
+ * @param i - the node index
57
+ * @returns the snapshot's id
58
+ */
59
+ originalAt(i: number): NodeId;
60
+ }
61
+
62
+ /**
63
+ * Whether an id can be written as a CX id unchanged: a safe integer, or the digits of an integer
64
+ * beyond 2^53 (the CX importers read those back as the same digits).
65
+ * @param id - the id
66
+ * @returns true when writable
67
+ */
68
+ function writableId(id: NodeId): boolean {
69
+ return typeof id === "number"
70
+ ? Number.isSafeInteger(id)
71
+ : BIG_INTEGER_TEXT.test(id) && !Number.isSafeInteger(Number(id));
72
+ }
73
+
74
+ /**
75
+ * The written node ids; under "error" an id that is not writable throws E_INVALID_ID, under
76
+ * "mangle" it gets the next unused integer.
77
+ * @param snapshot - the snapshot
78
+ * @param mode - the sanitizeIds option
79
+ * @param format - the format's display name, for the message
80
+ * @returns the ids
81
+ */
82
+ function writtenIds(snapshot: GraphSnapshot, mode: "error" | "mangle", format: string): WrittenIds {
83
+ const { ids } = snapshot;
84
+ const bad: number[] = [];
85
+ const used = new Set<number>();
86
+ for (let i = 0; i < ids.size; i++) {
87
+ const id = ids.idOf(i);
88
+ if (!writableId(id)) {
89
+ bad.push(i);
90
+ } else if (typeof id === "number") {
91
+ used.add(id);
92
+ }
93
+ }
94
+ if (bad.length > 0 && mode === "error") {
95
+ const first = ids.idOf(bad[0]);
96
+ throw new GraphFormatError(
97
+ "E_INVALID_ID",
98
+ `${bad.length} node id${plural(bad.length)} cannot be written as ${format} integers (first: ${JSON.stringify(first)} at index ${bad[0]}); pass sanitizeIds: "mangle" to rewrite them`,
99
+ { reason: "charset", charset: "integer", count: bad.length, index: bad[0] },
100
+ );
101
+ }
102
+ const renumbered = new Map<number, number>();
103
+ let next = 0;
104
+ for (const i of bad) {
105
+ while (used.has(next)) {
106
+ next++;
107
+ }
108
+ used.add(next);
109
+ renumbered.set(i, next);
110
+ }
111
+ return {
112
+ changed: bad.length,
113
+ idAt: (i: number): NodeId => {
114
+ const id = renumbered.get(i) ?? ids.idOf(i);
115
+ return typeof id === "string" ? `${RAW}${id}` : id;
116
+ },
117
+ isChanged: (i: number): boolean => renumbered.has(i),
118
+ originalAt: (i: number): NodeId => ids.idOf(i),
119
+ };
120
+ }
121
+
122
+ /**
123
+ * The `idCounter` of the node ids as written (the largest id plus one, NDEx's next free id).
124
+ * @param ids - the written ids
125
+ * @param count - the node count
126
+ * @returns the counter: a number, or a raw big integer for stringify()
127
+ * @category Plugin helpers
128
+ */
129
+ export function nextNodeId(ids: WrittenIds, count: number): NodeId {
130
+ let max = -1n;
131
+ for (let i = 0; i < count; i++) {
132
+ const id = ids.idAt(i);
133
+ const value = typeof id === "number" ? BigInt(id) : BigInt(id.slice(RAW.length));
134
+ if (value > max) {
135
+ max = value;
136
+ }
137
+ }
138
+ const next = max + 1n;
139
+ return next <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(next) : `${RAW}${next.toString()}`;
140
+ }
141
+
142
+ /**
143
+ * How many node ids are not writable unchanged.
144
+ * @param snapshot - the snapshot
145
+ * @returns the count
146
+ */
147
+ function unwritableIds(snapshot: GraphSnapshot): number {
148
+ let count = 0;
149
+ for (let i = 0; i < snapshot.ids.size; i++) {
150
+ if (!writableId(snapshot.ids.idOf(i))) {
151
+ count++;
152
+ }
153
+ }
154
+ return count;
155
+ }
156
+
157
+ /**
158
+ * The id notes and the written ids of a CX export: E_ID_CHARSET (export() throws) or
159
+ * W_ID_MANGLED for the ids that are not integers.
160
+ * @param snapshot - the snapshot
161
+ * @param common - the resolved common options
162
+ * @param format - the format's display name
163
+ * @param attribute - the attribute the originals are kept in
164
+ * @param note - records a note
165
+ * @returns the ids, or the error export() throws
166
+ * @category Plugin helpers
167
+ */
168
+ export function planNodeIds(
169
+ snapshot: GraphSnapshot,
170
+ common: ResolvedExportOptions,
171
+ format: string,
172
+ attribute: string,
173
+ note: CxNoteFn,
174
+ ): WrittenIds | GraphFormatError {
175
+ const unwritable = unwritableIds(snapshot);
176
+ if (unwritable > 0) {
177
+ note(
178
+ common.sanitizeIds === "mangle" ? LOSS.ID_MANGLED : LOSS.ID_CHARSET,
179
+ common.sanitizeIds === "mangle"
180
+ ? `${unwritable} node id${plural(unwritable)} ${agree(unwritable, "is", "are")} not integers, so they are renumbered; the original ids are written to the ${attribute} attribute, and an import with restoreMangledIds: true reads them back`
181
+ : `${unwritable} node id${plural(unwritable)} ${agree(unwritable, "is", "are")} not integers, so the save fails unless sanitizeIds is "mangle"`,
182
+ null,
183
+ unwritable,
184
+ );
185
+ }
186
+ try {
187
+ return writtenIds(snapshot, common.sanitizeIds, format);
188
+ } catch (err) {
189
+ if (err instanceof GraphFormatError) {
190
+ return err;
191
+ }
192
+ throw err;
193
+ }
194
+ }
195
+
196
+ /**
197
+ * The CX type of a scalar dtype.
198
+ * @param dtype - the dtype
199
+ * @param longOrigin - whether the source declared the column long
200
+ * @returns the type text
201
+ */
202
+ function scalarType(dtype: string, longOrigin: boolean): string {
203
+ switch (dtype) {
204
+ case "f64":
205
+ return longOrigin ? "long" : "double";
206
+ case "f32":
207
+ return "double";
208
+ case "i32":
209
+ case "u8":
210
+ return "integer";
211
+ case "u32":
212
+ return "long";
213
+ case "bool":
214
+ return "boolean";
215
+ default:
216
+ return "string";
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Whether every set value of an f64 column is integral (so a declared long stays long).
222
+ * @param column - the column
223
+ * @returns true when every set value is a safe integer
224
+ */
225
+ function allIntegral(column: Column): boolean {
226
+ for (let i = 0; i < column.length; i++) {
227
+ if (column.isSet(i) && !Number.isSafeInteger(column.value(i))) {
228
+ return false;
229
+ }
230
+ }
231
+ return true;
232
+ }
233
+
234
+ /**
235
+ * The declared CX type of a column: string / double / long / integer / boolean or a list of one;
236
+ * a json column (and a list of json items) is a string holding JSON text.
237
+ * @param column - the column
238
+ * @returns the type text
239
+ * @category Plugin helpers
240
+ */
241
+ export function declaredType(column: Column): string {
242
+ const { meta } = column;
243
+ const origin = meta.origin?.type ?? null;
244
+ const longOrigin = origin !== null && origin.endsWith("long") && (meta.dtype !== "f64" || allIntegral(column));
245
+ if (meta.dtype === "list") {
246
+ return meta.itemDtype === null || meta.itemDtype === "json"
247
+ ? "string"
248
+ : `list_of_${scalarType(meta.itemDtype, longOrigin)}`;
249
+ }
250
+ // a multi-component column (a color, a 3D vector) is written as a list of its components
251
+ return meta.components > 1 ? `list_of_${scalarType(meta.dtype, false)}` : scalarType(meta.dtype, longOrigin);
252
+ }
253
+
254
+ /**
255
+ * Count the positions with a non-finite x or y.
256
+ * @param position - the position column
257
+ * @returns the count
258
+ * @category Plugin helpers
259
+ */
260
+ export function nonFinitePositions(position: Column): number {
261
+ let count = 0;
262
+ for (let i = 0; i < position.length; i++) {
263
+ if (position.isSet(i)) {
264
+ const p = position.value(i) as ArrayLike<number>;
265
+ if (!Number.isFinite(p[0]) || !Number.isFinite(p[1])) {
266
+ count++;
267
+ }
268
+ }
269
+ }
270
+ return count;
271
+ }
272
+
273
+ /**
274
+ * The edge ids to write: the id role column's values when they are distinct safe integers, next
275
+ * unused integers for edges without one (W_EDGE_IDS_GENERATED).
276
+ * @param snapshot - the snapshot
277
+ * @param note - records a note
278
+ * @returns one id per edge
279
+ * @category Plugin helpers
280
+ */
281
+ export function planEdgeIds(snapshot: GraphSnapshot, note: CxNoteFn): number[] {
282
+ const column = snapshot.edges.byRole("id");
283
+ const used = new Set<number>();
284
+ let generated = 0;
285
+ const ids: (number | null)[] = keptEdgeIds(column, snapshot.edgeCount, used);
286
+ let next = 0;
287
+ const out: number[] = [];
288
+ for (let e = 0; e < snapshot.edgeCount; e++) {
289
+ let id = ids[e];
290
+ if (id === null) {
291
+ while (used.has(next)) {
292
+ next++;
293
+ }
294
+ id = next;
295
+ used.add(next);
296
+ generated++;
297
+ }
298
+ out.push(id);
299
+ }
300
+ if (column !== null && generated > 0) {
301
+ note(
302
+ LOSS.EDGE_IDS_GENERATED,
303
+ `${generated} edge${plural(generated)} ${agree(generated, "has", "have")} no distinct integer id in "${column.meta.name}"; they are written with generated ids`,
304
+ column.meta.name,
305
+ generated,
306
+ );
307
+ }
308
+ if (column !== null && column.dtype !== "f64") {
309
+ note(
310
+ LOSS.DTYPE,
311
+ `edge id column "${column.meta.name}" is ${column.dtype}; CX edge ids are integers and read back as f64`,
312
+ column.meta.name,
313
+ snapshot.edgeCount - column.nullCount,
314
+ );
315
+ }
316
+ return out;
317
+ }
318
+
319
+ /**
320
+ * The edge ids an id column can keep: its distinct safe integers (numbers, or text that reads as one).
321
+ * @param column - the edge id column, or null
322
+ * @param edgeCount - the number of edges
323
+ * @param used - receives the kept ids
324
+ * @returns the kept id per edge, null where it cannot be kept
325
+ */
326
+ function keptEdgeIds(column: Column | null, edgeCount: number, used: Set<number>): (number | null)[] {
327
+ const ids: (number | null)[] = new Array<number | null>(edgeCount).fill(null);
328
+ if (column === null) {
329
+ return ids;
330
+ }
331
+ for (let e = 0; e < edgeCount; e++) {
332
+ const value = column.isSet(e) ? column.value(e) : undefined;
333
+ const n = typeof value === "number" || typeof value === "string" ? Number(value) : Number.NaN;
334
+ if (Number.isSafeInteger(n) && !used.has(n)) {
335
+ ids[e] = n === 0 ? 0 : n;
336
+ used.add(n);
337
+ }
338
+ }
339
+ return ids;
340
+ }
341
+
342
+ /**
343
+ * The direction notes: every CX edge is directed, so an undirected snapshot (or the undirected
344
+ * pairs of a mixed one, folded under onMixedDirection) is written directed, and a mutual pair as
345
+ * two edges without its mark.
346
+ * @param snapshot - the snapshot
347
+ * @param folding - the pair folding
348
+ * @param common - the resolved common options
349
+ * @param undirectedCode - the format's "undirected written as directed" code
350
+ * @param note - records a note
351
+ * @category Plugin helpers
352
+ */
353
+ export function directionNotes(
354
+ snapshot: GraphSnapshot,
355
+ folding: PairFolding,
356
+ common: ResolvedExportOptions,
357
+ undirectedCode: string,
358
+ note: CxNoteFn,
359
+ ): void {
360
+ if (!snapshot.directed) {
361
+ note(
362
+ undirectedCode,
363
+ `the snapshot is undirected; every edge is written as a directed edge (${snapshot.edgeCount} edge${plural(snapshot.edgeCount)})`,
364
+ null,
365
+ snapshot.edgeCount,
366
+ );
367
+ } else if (common.onMixedDirection !== "error") {
368
+ let undirected = 0;
369
+ for (let e = 0; e < snapshot.edgeCount; e++) {
370
+ if (!folding.folded(e) && !folding.sourceDirected(e)) {
371
+ undirected++;
372
+ }
373
+ }
374
+ if (undirected > 0) {
375
+ note(
376
+ undirectedCode,
377
+ `${undirected} undirected edge${plural(undirected)} ${agree(undirected, "is", "are")} written as one directed edge each (a pair folded to its primary); CX has no undirected edge`,
378
+ null,
379
+ undirected,
380
+ );
381
+ }
382
+ }
383
+ if (folding.mutualCount > 0) {
384
+ note(
385
+ LOSS.MUTUAL_EXPANDED,
386
+ `${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, "is", "are")} written as two directed edges; the mutual mark is lost`,
387
+ null,
388
+ folding.mutualCount,
389
+ );
390
+ }
391
+ }
392
+
393
+ /**
394
+ * The note recorder of a plan and its notes.
395
+ * @returns the notes and the recorder
396
+ * @category Plugin helpers
397
+ */
398
+ export function noteList(): { notes: LossNote[]; note: CxNoteFn } {
399
+ const notes: LossNote[] = [];
400
+ const note: CxNoteFn = (code, message, column = null, count = null) => {
401
+ notes.push(Object.freeze({ code, message, column, count }));
402
+ };
403
+ return { notes, note };
404
+ }
405
+
406
+ /**
407
+ * The JSON text of a value, keeping -0 and writing the raw big-integer ids of idAt() as numbers.
408
+ * @param value - the value
409
+ * @returns the text
410
+ * @category Plugin helpers
411
+ */
412
+ export function stringify(value: unknown): string {
413
+ const text = JSON.stringify(value, (_key, v: unknown) => (Object.is(v, -0) ? `${RAW}-0` : v));
414
+ return text.includes(String.raw`\u0000cx:`) ? text.replaceAll(RAW_JSON, "$1") : text;
415
+ }
416
+
417
+ /**
418
+ * The text of one aspect block, element by element.
419
+ * @param aspect - the aspect name
420
+ * @param elements - the JSON texts of its elements
421
+ * @yields the block's text
422
+ * @returns nothing
423
+ */
424
+ export function* aspectBlock(aspect: string, elements: Iterable<string>): Generator<string, void, undefined> {
425
+ yield `{${JSON.stringify(aspect)}:[`;
426
+ let first = true;
427
+ for (const element of elements) {
428
+ yield first ? `\n${element}` : `,\n${element}`;
429
+ first = false;
430
+ }
431
+ yield "]},\n";
432
+ }
@@ -15,16 +15,32 @@
15
15
 
16
16
  import { type Dtype, GraphFormatError, type ScalarDtype } from "@graphty/graph-format";
17
17
 
18
+ import { withArticle } from "./plural.js";
18
19
  import { parseTemporal, type TemporalKind } from "./temporal.js";
19
20
 
20
- /** The formats whose declarations this table covers. */
21
+ /**
22
+ * The formats whose declarations this table covers.
23
+ * @category Plugin helpers
24
+ */
21
25
  export type DeclaringFormat = "gexf" | "graphml" | "gml" | "neo4j";
22
26
 
23
27
  /** How the text of one scalar value (or one list item) is parsed. */
24
28
  type ValueKind =
25
- "boolean" | "integer" | "long" | "float" | "double" | "string" | "temporal" | "duration" | "point" | "json";
29
+ | "boolean"
30
+ | "integer"
31
+ | "long"
32
+ | "float"
33
+ | "double"
34
+ | "string"
35
+ | "temporal"
36
+ | "duration"
37
+ | "point"
38
+ | "json";
26
39
 
27
- /** The resolved storage of a declared type. */
40
+ /**
41
+ * The resolved storage of a declared type.
42
+ * @category Plugin helpers
43
+ */
28
44
  export interface DeclaredTypeSpec {
29
45
  /** The declared type text as given by the file (origin.type). */
30
46
  readonly declared: string;
@@ -140,6 +156,7 @@ const I32_MAX = 2147483647;
140
156
  * @param type - the type text as written (matched case-insensitively; GEXF `list*` and Neo4j `[]` denote lists)
141
157
  * @param long - how declared long / integer-64 columns are stored (the importer option)
142
158
  * @returns the spec, or null when the format does not define the type (the importer reports it and keeps the text)
159
+ * @category Plugin helpers
143
160
  */
144
161
  export function mapDeclaredType(
145
162
  format: DeclaringFormat,
@@ -188,6 +205,7 @@ export function mapDeclaredType(
188
205
  * The spec of an untyped attribute: a string column with the given (or absent) type text.
189
206
  * @param declared - the type text to record in origin.type, or null
190
207
  * @returns a string spec
208
+ * @category Plugin helpers
191
209
  */
192
210
  export function stringSpec(declared: string | null): DeclaredTypeSpec {
193
211
  return {
@@ -209,6 +227,7 @@ export function stringSpec(declared: string | null): DeclaredTypeSpec {
209
227
  * @param kind - the value kind
210
228
  * @param temporal - the temporal kind when `kind` is "temporal"
211
229
  * @returns a boolean, a number, a string or (point / json) a JSON value; E_COLUMN_TYPE when the text is not of the kind
230
+ * @category Plugin helpers
212
231
  */
213
232
  export function parseScalarText(text: string, kind: ValueKind, temporal: TemporalKind | null = null): unknown {
214
233
  switch (kind) {
@@ -267,6 +286,7 @@ export function parseScalarText(text: string, kind: ValueKind, temporal: Tempora
267
286
  * Parse a boolean text the way the formats write it: `true` / `false` in any case, or `1` / `0`.
268
287
  * @param text - the value text
269
288
  * @returns the boolean, or null when the text is neither
289
+ * @category Plugin helpers
270
290
  */
271
291
  export function parseBooleanText(text: string): boolean | null {
272
292
  switch (text.trim().toLowerCase()) {
@@ -287,6 +307,7 @@ export function parseBooleanText(text: string): boolean | null {
287
307
  * @param text - the value text
288
308
  * @param kind - float or double, for the error
289
309
  * @returns the number
310
+ * @category Plugin helpers
290
311
  */
291
312
  export function parseDecimalText(text: string, kind: ValueKind = "double"): number {
292
313
  const trimmed = text.trim();
@@ -309,11 +330,24 @@ export function parseDecimalText(text: string, kind: ValueKind = "double"): numb
309
330
  }
310
331
  }
311
332
 
333
+ /**
334
+ * Whether a number text is finite as written but too large for a double (`1e400`, a 400-digit
335
+ * integer), so it parses as Infinity: a value the importer should report, unlike `INF`.
336
+ * @param text - the value text
337
+ * @returns true when the text overflows
338
+ * @category Plugin helpers
339
+ */
340
+ export function overflowsToInfinity(text: string): boolean {
341
+ const trimmed = text.trim();
342
+ return /^[+-]?[0-9.]/.test(trimmed) && Number(trimmed) === (trimmed.startsWith("-") ? -Infinity : Infinity);
343
+ }
344
+
312
345
  /**
313
346
  * Parse a Neo4j point literal `{x:1.0, y:2.0, crs:'cartesian'}` (also `latitude` / `longitude` /
314
347
  * `height` / `z` / `srid`) into a JSON object; a JSON object text is accepted as well.
315
348
  * @param text - the value text
316
349
  * @returns an object with numeric coordinates and string crs
350
+ * @category Plugin helpers
317
351
  */
318
352
  export function parsePointText(text: string): Readonly<Record<string, number | string>> {
319
353
  const trimmed = text.trim();
@@ -370,5 +404,5 @@ function parseJsonText(text: string): unknown {
370
404
  */
371
405
  function typeError(text: string, kind: ValueKind): GraphFormatError {
372
406
  const shown = text.length > 40 ? `${text.slice(0, 40)}...` : text;
373
- return new GraphFormatError("E_COLUMN_TYPE", `"${shown}" is not a ${kind}`, { value: text, kind });
407
+ return new GraphFormatError("E_COLUMN_TYPE", `"${shown}" is not ${withArticle(kind)}`, { value: text, kind });
374
408
  }