@graphty/graph-io 0.3.25 → 0.3.27

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-DrXtu_96.js +56 -0
  4. package/dist/chunks/choose-DrXtu_96.js.map +1 -0
  5. package/dist/chunks/constants-ikG85dT8.js +231 -0
  6. package/dist/chunks/constants-ikG85dT8.js.map +1 -0
  7. package/dist/chunks/{escape-B-tkk_Cl.js → escape-D1HPTUrP.js} +390 -99
  8. package/dist/chunks/escape-D1HPTUrP.js.map +1 -0
  9. package/dist/chunks/export-CHd4tQE2.js +4333 -0
  10. package/dist/chunks/export-CHd4tQE2.js.map +1 -0
  11. package/dist/chunks/{importer-eUREhBGj.js → exporter-D23CKNqF.js} +4969 -3201
  12. package/dist/chunks/exporter-D23CKNqF.js.map +1 -0
  13. package/dist/chunks/{exporter-DIeGJXAZ.js → exporter-DfWTgrti.js} +23 -21
  14. package/dist/chunks/exporter-DfWTgrti.js.map +1 -0
  15. package/dist/chunks/exporter-DhtW6FxK.js +3465 -0
  16. package/dist/chunks/exporter-DhtW6FxK.js.map +1 -0
  17. package/dist/chunks/{exporter-BGrsWamJ.js → exporter-IHv4nkCm.js} +38 -229
  18. package/dist/chunks/exporter-IHv4nkCm.js.map +1 -0
  19. package/dist/chunks/{importer-BWY2FFc5.js → importer-B1wmPQjr.js} +255 -77
  20. package/dist/chunks/importer-B1wmPQjr.js.map +1 -0
  21. package/dist/chunks/{importer-D_e7e7LX.js → importer-B2W_58pz.js} +399 -146
  22. package/dist/chunks/importer-B2W_58pz.js.map +1 -0
  23. package/dist/chunks/importer-BSALvkui.js +2811 -0
  24. package/dist/chunks/importer-BSALvkui.js.map +1 -0
  25. package/dist/chunks/{importer-vi3bSdtw.js → importer-BVRE--Un.js} +510 -77
  26. package/dist/chunks/importer-BVRE--Un.js.map +1 -0
  27. package/dist/chunks/{importer-DET1tg6s.js → importer-CIAzt-wo.js} +1689 -312
  28. package/dist/chunks/importer-CIAzt-wo.js.map +1 -0
  29. package/dist/chunks/{importer-DIrbbnAf.js → importer-DpEW5zeG.js} +585 -226
  30. package/dist/chunks/importer-DpEW5zeG.js.map +1 -0
  31. package/dist/chunks/{importer-zGLo8Dg_.js → importer-z_FL4VMb.js} +488 -161
  32. package/dist/chunks/importer-z_FL4VMb.js.map +1 -0
  33. package/dist/chunks/json-elements-BAmNBZok.js +1225 -0
  34. package/dist/chunks/json-elements-BAmNBZok.js.map +1 -0
  35. package/dist/chunks/ontology-export-Bab4eUA8.js +357 -0
  36. package/dist/chunks/ontology-export-Bab4eUA8.js.map +1 -0
  37. package/dist/chunks/{records-dbRkxwaq.js → records-CdlvL4RO.js} +298 -114
  38. package/dist/chunks/records-CdlvL4RO.js.map +1 -0
  39. package/dist/chunks/{text-Dr0Ifpag.js → text-DzXjAiTl.js} +29 -11
  40. package/dist/chunks/text-DzXjAiTl.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 +952 -262
  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 +344 -87
  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 +565 -158
  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 +21 -3
  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 +39 -22
  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 +869 -189
  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 +3 -1
  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 +402 -85
  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 +146 -33
  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 +682 -287
  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 +227 -80
  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 +101 -27
  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 +110 -28
  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 +239 -86
  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 +67 -35
  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 +186 -54
  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 +21 -22
  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 +8 -3
  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 +40 -6
  468. package/src/common/direction.ts +78 -51
  469. package/src/common/escape.ts +39 -22
  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 +1035 -199
  475. package/src/common/line-format.ts +249 -0
  476. package/src/common/lists.ts +7 -2
  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 +479 -90
  487. package/src/common/zip.ts +169 -7
  488. package/src/formats/csv/exporter.ts +202 -47
  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 +890 -302
  496. package/src/formats/cx/index.ts +4 -3
  497. package/src/formats/cx2/exporter.ts +62 -339
  498. package/src/formats/cx2/importer.ts +318 -87
  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 +142 -34
  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 +113 -28
  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 +321 -102
  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 +90 -42
  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 +216 -55
  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 +36 -28
  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 +12 -4
  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,472 @@
1
+ /**
2
+ * Compare two snapshots node by node, edge by edge and value by value, for testing a format plugin:
3
+ * read a file, save it, read the saved file back, and compare. Every difference should be one that
4
+ * the save's checkExport() notes announced.
5
+ */
6
+
7
+ import { type Column, type GraphSnapshot } from "@graphty/graph-format";
8
+
9
+ /**
10
+ * One difference between two snapshots.
11
+ * @category Plugin helpers
12
+ */
13
+ export interface SnapshotDiff {
14
+ /** Where: "directed", "ids[3]", "nodes.label[4]", "edges.weight[0]", "extensions.temporal:node:price.rowCount"... */
15
+ readonly path: string;
16
+ /** The value in the expected snapshot. */
17
+ readonly expected: unknown;
18
+ /** The value in the actual snapshot. */
19
+ readonly actual: unknown;
20
+ /** A one-line description. */
21
+ readonly message: string;
22
+ }
23
+
24
+ /**
25
+ * What compareSnapshots() compares.
26
+ * @category Plugin helpers
27
+ */
28
+ export interface CompareOptions {
29
+ /** Column names to skip in every table (format-owned helpers an exporter adds, for instance). */
30
+ readonly ignoreColumns?: readonly string[] | undefined;
31
+ /** Column roles to skip in every table. */
32
+ readonly ignoreRoles?: readonly string[] | undefined;
33
+ /** Whether the actual snapshot may hold columns the expected one lacks (default true). */
34
+ readonly allowExtraColumns?: boolean | undefined;
35
+ /** Whether dtypes must match (default true); false compares values only. */
36
+ readonly dtypes?: boolean | undefined;
37
+ /** Whether roles must match (default true). */
38
+ readonly roles?: boolean | undefined;
39
+ /** Whether origin.type must match (default false). */
40
+ readonly originType?: boolean | undefined;
41
+ /** Absolute tolerance for numeric cell and weight comparisons (default 0: Object.is). */
42
+ readonly tolerance?: number | undefined;
43
+ /** Whether the explicit / defaulted status of weights must match (default true). */
44
+ readonly weightExplicitness?: boolean | undefined;
45
+ /** Whether extension tables are compared (default true). */
46
+ readonly extensions?: boolean | undefined;
47
+ /** Stop after this many differences (default 50). */
48
+ readonly limit?: number | undefined;
49
+ }
50
+
51
+ /**
52
+ * Compare two snapshots: the direction, the node ids, the edges, the weights and every attribute
53
+ * value. Use it to test a format plugin: read a file, save it in your format, read the saved file
54
+ * back, and compare the two graphs. Each difference has a `path` ("ids[3]", "nodes.label[4]",
55
+ * "edges.weight[0]") and a one-line `message`; every one should match a note that `checkExport()`
56
+ * returned for the save.
57
+ * @example
58
+ * ```ts
59
+ * const notes = checkExport(original, "pairs");
60
+ * const readBack = (await importGraph(await exportGraphToString(original, "pairs"), { format: "pairs" })).snapshot;
61
+ * console.log(describeDiffs(compareSnapshots(original, readBack)));
62
+ * ```
63
+ * @param expected - the graph you saved
64
+ * @param actual - the graph read back from the saved file
65
+ * @param options - what to compare
66
+ * @returns the differences, empty when the graphs are the same
67
+ * @category Plugin helpers
68
+ */
69
+ export function compareSnapshots(
70
+ expected: GraphSnapshot,
71
+ actual: GraphSnapshot,
72
+ options: CompareOptions = {},
73
+ ): SnapshotDiff[] {
74
+ const diffs: SnapshotDiff[] = [];
75
+ const limit = options.limit ?? 50;
76
+ const tolerance = options.tolerance ?? 0;
77
+ const ctx: CompareContext = {
78
+ options,
79
+ diff: (path, e, a, message) => {
80
+ diffs.push({
81
+ path,
82
+ expected: e,
83
+ actual: a,
84
+ message: message ?? `${path}: expected ${show(e)}, got ${show(a)}`,
85
+ });
86
+ if (diffs.length >= limit) {
87
+ throw new LimitReached();
88
+ }
89
+ },
90
+ same: (e, a) => valuesEqual(e, a, tolerance),
91
+ };
92
+ try {
93
+ compareGraphs(expected, actual, ctx);
94
+ } catch (err) {
95
+ if (!(err instanceof LimitReached)) {
96
+ throw err;
97
+ }
98
+ }
99
+ return diffs;
100
+ }
101
+
102
+ /** Thrown by the recorder once the limit of differences is reached, to end the walk. */
103
+ class LimitReached extends Error {}
104
+
105
+ /** What every comparison step shares: the options, the recorder and the value comparator. */
106
+ interface CompareContext {
107
+ readonly options: CompareOptions;
108
+ /** Records a difference (with a default message); throws LimitReached at the limit. */
109
+ readonly diff: (path: string, e: unknown, a: unknown, message?: string) => void;
110
+ /** Value equality under the tolerance. */
111
+ readonly same: (e: unknown, a: unknown) => boolean;
112
+ }
113
+
114
+ /** A table shape both AttributeTable and extension tables satisfy. */
115
+ interface TableLike extends Iterable<Column> {
116
+ readonly rowCount: number;
117
+ names(): readonly string[];
118
+ get(name: string): Column | null;
119
+ }
120
+
121
+ /**
122
+ * Compare two snapshots step by step: the counts, the ids, the topology, the weights, the tables.
123
+ * @param expected - the reference
124
+ * @param actual - the snapshot under test
125
+ * @param ctx - the comparison context
126
+ */
127
+ function compareGraphs(expected: GraphSnapshot, actual: GraphSnapshot, ctx: CompareContext): void {
128
+ const { diff } = ctx;
129
+ if (expected.directed !== actual.directed) {
130
+ diff("directed", expected.directed, actual.directed);
131
+ }
132
+ if (expected.nodeCount !== actual.nodeCount) {
133
+ diff("nodeCount", expected.nodeCount, actual.nodeCount);
134
+ }
135
+ if (expected.edgeCount !== actual.edgeCount) {
136
+ diff("edgeCount", expected.edgeCount, actual.edgeCount);
137
+ }
138
+ compareIds(expected, actual, diff);
139
+ if (expected.nodeCount !== actual.nodeCount || expected.edgeCount !== actual.edgeCount) {
140
+ return;
141
+ }
142
+ compareTopology(expected, actual, diff);
143
+ compareWeights(expected, actual, ctx);
144
+ compareTables("nodes", expected.nodes, actual.nodes, ctx);
145
+ compareTables("edges", expected.edges, actual.edges, ctx);
146
+ compareTables("graph", expected.graph, actual.graph, ctx);
147
+ if (ctx.options.extensions !== false) {
148
+ compareExtensions(expected, actual, ctx);
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Compare the node ids in index order.
154
+ * @param expected - the reference
155
+ * @param actual - the snapshot under test
156
+ * @param diff - the recorder
157
+ */
158
+ function compareIds(expected: GraphSnapshot, actual: GraphSnapshot, diff: CompareContext["diff"]): void {
159
+ const expectedIds = expected.ids.toArray();
160
+ const actualIds = actual.ids.toArray();
161
+ const n = Math.min(expectedIds.length, actualIds.length);
162
+ for (let i = 0; i < n; i++) {
163
+ if (!Object.is(expectedIds[i], actualIds[i])) {
164
+ diff(`ids[${i}]`, expectedIds[i], actualIds[i]);
165
+ }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Compare the topology: the CSR arrays (identical when node order and edge order survived), then the
171
+ * orientation of every logical edge.
172
+ * @param expected - the reference
173
+ * @param actual - the snapshot under test, with as many nodes and edges
174
+ * @param diff - the recorder
175
+ */
176
+ function compareTopology(expected: GraphSnapshot, actual: GraphSnapshot, diff: CompareContext["diff"]): void {
177
+ if (!typedEqual(expected.rowPtr, actual.rowPtr)) {
178
+ diff("rowPtr", expected.rowPtr, actual.rowPtr, "rowPtr differs");
179
+ }
180
+ if (!typedEqual(expected.colIdx, actual.colIdx)) {
181
+ diff("colIdx", expected.colIdx, actual.colIdx, "colIdx differs");
182
+ }
183
+ const el = expected.edgeList();
184
+ const al = actual.edgeList();
185
+ for (let e = 0; e < expected.edgeCount; e++) {
186
+ if (el.src[e] !== al.src[e] || el.dst[e] !== al.dst[e]) {
187
+ diff(`edge[${e}]`, `${el.src[e]}->${el.dst[e]}`, `${al.src[e]}->${al.dst[e]}`);
188
+ }
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Compare the weights of two snapshots: the exact weight column when both have one, the 32-bit
194
+ * weights otherwise.
195
+ * @param expected - the reference
196
+ * @param actual - the snapshot under test
197
+ * @param ctx - the comparison context
198
+ */
199
+ function compareWeights(expected: GraphSnapshot, actual: GraphSnapshot, ctx: CompareContext): void {
200
+ if (expected.flags.weighted !== actual.flags.weighted) {
201
+ ctx.diff("flags.weighted", expected.flags.weighted, actual.flags.weighted);
202
+ return;
203
+ }
204
+ if (!expected.flags.weighted) {
205
+ return;
206
+ }
207
+ const eShadow = expected.edges.byRole("weight");
208
+ const aShadow = actual.edges.byRole("weight");
209
+ if (eShadow !== null && aShadow !== null) {
210
+ compareExactWeights(expected.edgeCount, eShadow, aShadow, ctx);
211
+ return;
212
+ }
213
+ if (ctx.options.weightExplicitness !== false && (eShadow === null) !== (aShadow === null)) {
214
+ ctx.diff(
215
+ "weightColumn",
216
+ eShadow !== null,
217
+ aShadow !== null,
218
+ "one snapshot has a role-weight column, the other does not",
219
+ );
220
+ }
221
+ const ew = expected.edgeList().weights;
222
+ const aw = actual.edgeList().weights;
223
+ for (let e = 0; e < expected.edgeCount; e++) {
224
+ const ev = ew === null ? 1 : ew[e];
225
+ const av = aw === null ? 1 : aw[e];
226
+ if (!ctx.same(ev, av)) {
227
+ ctx.diff(`weight[${e}]`, ev, av);
228
+ }
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Compare the exact weight columns of two snapshots: which edges have an explicit weight, and its value.
234
+ * @param edgeCount - the number of edges
235
+ * @param expected - the reference's weight column
236
+ * @param actual - the weight column under test
237
+ * @param ctx - the comparison context
238
+ */
239
+ function compareExactWeights(edgeCount: number, expected: Column, actual: Column, ctx: CompareContext): void {
240
+ for (let e = 0; e < edgeCount; e++) {
241
+ const eSet = expected.isSet(e);
242
+ const aSet = actual.isSet(e);
243
+ if (ctx.options.weightExplicitness !== false && eSet !== aSet) {
244
+ ctx.diff(`weightExplicit[${e}]`, eSet, aSet);
245
+ } else if (eSet && aSet && !ctx.same(expected.value(e), actual.value(e))) {
246
+ ctx.diff(`weight[${e}]`, expected.value(e), actual.value(e));
247
+ }
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Compare the extension tables: which exist, their row counts and their columns.
253
+ * @param expected - the reference
254
+ * @param actual - the snapshot under test
255
+ * @param ctx - the comparison context
256
+ */
257
+ function compareExtensions(expected: GraphSnapshot, actual: GraphSnapshot, ctx: CompareContext): void {
258
+ for (const [name, table] of expected.extensions) {
259
+ const other = actual.extensions.get(name);
260
+ if (other === undefined) {
261
+ ctx.diff(`extensions.${name}`, "present", "absent");
262
+ } else if (table.rowCount === other.rowCount) {
263
+ compareTables(`extensions.${name}`, table, other, ctx);
264
+ } else {
265
+ ctx.diff(`extensions.${name}.rowCount`, table.rowCount, other.rowCount);
266
+ }
267
+ }
268
+ if (ctx.options.allowExtraColumns === false) {
269
+ for (const name of actual.extensions.keys()) {
270
+ if (!expected.extensions.has(name)) {
271
+ ctx.diff(`extensions.${name}`, "absent", "present");
272
+ }
273
+ }
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Compare the columns of one table.
279
+ * @param label - the table name for paths
280
+ * @param expected - the reference table
281
+ * @param actual - the table under test
282
+ * @param ctx - the comparison context
283
+ */
284
+ function compareTables(label: string, expected: TableLike, actual: TableLike, ctx: CompareContext): void {
285
+ const ignoreNames = new Set(ctx.options.ignoreColumns ?? []);
286
+ const ignoreRoles = new Set(ctx.options.ignoreRoles ?? []);
287
+ // the role-weight shadow column is compared by the weights step, not as a declared column
288
+ const skip = (column: Column): boolean => {
289
+ const { name, role } = column.meta;
290
+ return (
291
+ ignoreNames.has(name) ||
292
+ (role !== null && (ignoreRoles.has(role) || (label === "edges" && role === "weight")))
293
+ );
294
+ };
295
+ for (const column of expected) {
296
+ if (skip(column)) {
297
+ continue;
298
+ }
299
+ const path = `${label}.${column.meta.name}`;
300
+ const other = actual.get(column.meta.name);
301
+ if (other === null) {
302
+ ctx.diff(path, "present", "absent", `${path}: column missing after round trip`);
303
+ } else {
304
+ compareColumn(path, column, other, ctx);
305
+ }
306
+ }
307
+ if (ctx.options.allowExtraColumns === false) {
308
+ for (const column of actual) {
309
+ if (!skip(column) && expected.get(column.meta.name) === null) {
310
+ const path = `${label}.${column.meta.name}`;
311
+ ctx.diff(path, "absent", "present", `${path}: extra column after round trip`);
312
+ }
313
+ }
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Compare one column: its declaration, then every cell.
319
+ * @param path - the column's path for messages
320
+ * @param column - the reference column
321
+ * @param other - the column under test
322
+ * @param ctx - the comparison context
323
+ */
324
+ function compareColumn(path: string, column: Column, other: Column, ctx: CompareContext): void {
325
+ compareDeclaration(path, column, other, ctx);
326
+ if (column.length !== other.length) {
327
+ ctx.diff(`${path}.length`, column.length, other.length);
328
+ return;
329
+ }
330
+ for (let r = 0; r < column.length; r++) {
331
+ const eSet = column.isSet(r);
332
+ const aSet = other.isSet(r);
333
+ if (eSet !== aSet) {
334
+ ctx.diff(`${path}[${r}]`, eSet ? column.value(r) : undefined, aSet ? other.value(r) : undefined);
335
+ } else if (eSet) {
336
+ const ev = cellValue(column, r);
337
+ const av = cellValue(other, r);
338
+ if (!ctx.same(ev, av)) {
339
+ ctx.diff(`${path}[${r}]`, ev, av);
340
+ }
341
+ }
342
+ }
343
+ }
344
+
345
+ /**
346
+ * Compare what two columns declare: dtype, item dtype, components, role and origin type, as the
347
+ * options ask.
348
+ * @param path - the column's path for messages
349
+ * @param column - the reference column
350
+ * @param other - the column under test
351
+ * @param ctx - the comparison context
352
+ */
353
+ function compareDeclaration(path: string, column: Column, other: Column, ctx: CompareContext): void {
354
+ const { options, diff } = ctx;
355
+ const e = column.meta;
356
+ const a = other.meta;
357
+ if (options.dtypes !== false) {
358
+ for (const key of ["dtype", "itemDtype", "components"] as const) {
359
+ if (e[key] !== a[key]) {
360
+ diff(`${path}.${key}`, e[key], a[key]);
361
+ }
362
+ }
363
+ }
364
+ if (options.roles !== false && e.role !== a.role) {
365
+ diff(`${path}.role`, e.role, a.role);
366
+ }
367
+ const eType = e.origin?.type ?? null;
368
+ const aType = a.origin?.type ?? null;
369
+ if (options.originType === true && eType !== aType) {
370
+ diff(`${path}.origin.type`, eType, aType);
371
+ }
372
+ }
373
+
374
+ /**
375
+ * The comparable value of a set cell: list rows through sliceOf, json rows through values, the
376
+ * typed accessor otherwise (a components > 1 subarray becomes a plain array).
377
+ * @param column - the column
378
+ * @param row - the row
379
+ * @returns the value
380
+ */
381
+ function cellValue(column: Column, row: number): unknown {
382
+ switch (column.dtype) {
383
+ case "list":
384
+ return [...column.sliceOf(row)];
385
+ case "json":
386
+ return column.values[row];
387
+ default: {
388
+ const value = column.value(row);
389
+ return ArrayBuffer.isView(value) ? Array.from(value as ArrayLike<number>) : value;
390
+ }
391
+ }
392
+ }
393
+
394
+ /**
395
+ * Deep equality with a numeric tolerance (for the tests).
396
+ * @param e - expected
397
+ * @param a - actual
398
+ * @param tolerance - absolute tolerance for numbers
399
+ * @returns true when equal
400
+ */
401
+ export function valuesEqual(e: unknown, a: unknown, tolerance: number): boolean {
402
+ if (typeof e === "number" && typeof a === "number") {
403
+ if (Object.is(e, a)) {
404
+ return true;
405
+ }
406
+ return Number.isFinite(e) && Number.isFinite(a) && Math.abs(e - a) <= tolerance;
407
+ }
408
+ if (Array.isArray(e) || ArrayBuffer.isView(e)) {
409
+ const ea = Array.from(e as ArrayLike<unknown>);
410
+ if (!(Array.isArray(a) || ArrayBuffer.isView(a))) {
411
+ return false;
412
+ }
413
+ const aa = Array.from(a as ArrayLike<unknown>);
414
+ return ea.length === aa.length && ea.every((v, i) => valuesEqual(v, aa[i], tolerance));
415
+ }
416
+ if (typeof e === "object" && e !== null && typeof a === "object" && a !== null) {
417
+ const eo = e as Record<string, unknown>;
418
+ const ao = a as Record<string, unknown>;
419
+ const keys = Object.keys(eo);
420
+ if (keys.length !== Object.keys(ao).length) {
421
+ return false;
422
+ }
423
+ return keys.every((k) => Object.hasOwn(ao, k) && valuesEqual(eo[k], ao[k], tolerance));
424
+ }
425
+ return Object.is(e, a);
426
+ }
427
+
428
+ /**
429
+ * Element-wise equality of two typed arrays.
430
+ * @param a - one array
431
+ * @param b - the other
432
+ * @returns true when same length and contents
433
+ */
434
+ function typedEqual(a: ArrayLike<number>, b: ArrayLike<number>): boolean {
435
+ if (a.length !== b.length) {
436
+ return false;
437
+ }
438
+ for (let i = 0; i < a.length; i++) {
439
+ if (a[i] !== b[i]) {
440
+ return false;
441
+ }
442
+ }
443
+ return true;
444
+ }
445
+
446
+ /**
447
+ * A short text of a value for messages.
448
+ * @param v - the value
449
+ * @returns JSON when possible, else String()
450
+ */
451
+ function show(v: unknown): string {
452
+ if (ArrayBuffer.isView(v)) {
453
+ const items = Array.from(v as unknown as ArrayLike<number>);
454
+ return `[${items.slice(0, 8).join(", ")}${items.length > 8 ? ", ..." : ""}]`;
455
+ }
456
+ try {
457
+ const text = JSON.stringify(v);
458
+ return text ?? String(v);
459
+ } catch {
460
+ return String(v);
461
+ }
462
+ }
463
+
464
+ /**
465
+ * The differences compareSnapshots() found, one per line, for printing.
466
+ * @param diffs - the differences
467
+ * @returns one line per difference, "no differences" when empty
468
+ * @category Plugin helpers
469
+ */
470
+ export function describeDiffs(diffs: readonly SnapshotDiff[]): string {
471
+ return diffs.length === 0 ? "no differences" : diffs.map((d) => ` - ${d.message}`).join("\n");
472
+ }