@graphty/graph-io 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +250 -28
  3. package/dist/chunks/children-CL3Cy0ez.js +238 -0
  4. package/dist/chunks/children-CL3Cy0ez.js.map +1 -0
  5. package/dist/chunks/escape-DyI8JofU.js +938 -0
  6. package/dist/chunks/escape-DyI8JofU.js.map +1 -0
  7. package/dist/chunks/importer-CQnJuWJw.js +2987 -0
  8. package/dist/chunks/importer-CQnJuWJw.js.map +1 -0
  9. package/dist/chunks/importer-CpCpfbxr.js +2015 -0
  10. package/dist/chunks/importer-CpCpfbxr.js.map +1 -0
  11. package/dist/chunks/importer-DbnGYr3_.js +2342 -0
  12. package/dist/chunks/importer-DbnGYr3_.js.map +1 -0
  13. package/dist/chunks/importer-GozH8DkN.js +3050 -0
  14. package/dist/chunks/importer-GozH8DkN.js.map +1 -0
  15. package/dist/chunks/records-CGpxszm1.js +605 -0
  16. package/dist/chunks/records-CGpxszm1.js.map +1 -0
  17. package/dist/chunks/text-CajMdVFy.js +189 -0
  18. package/dist/chunks/text-CajMdVFy.js.map +1 -0
  19. package/dist/chunks/writer-DxSKC7TL.js +2842 -0
  20. package/dist/chunks/writer-DxSKC7TL.js.map +1 -0
  21. package/dist/csv.d.ts +1 -0
  22. package/dist/csv.js +1702 -0
  23. package/dist/csv.js.map +1 -0
  24. package/dist/dot.d.ts +1 -0
  25. package/dist/dot.js +8 -0
  26. package/dist/dot.js.map +1 -0
  27. package/dist/gexf.d.ts +1 -0
  28. package/dist/gexf.js +3466 -0
  29. package/dist/gexf.js.map +1 -0
  30. package/dist/gml.d.ts +1 -0
  31. package/dist/gml.js +2647 -0
  32. package/dist/gml.js.map +1 -0
  33. package/dist/graph-io.d.ts +1 -0
  34. package/dist/graph-io.js +790 -0
  35. package/dist/graph-io.js.map +1 -0
  36. package/dist/graphml.d.ts +1 -0
  37. package/dist/graphml.js +8 -0
  38. package/dist/graphml.js.map +1 -0
  39. package/dist/json.d.ts +1 -0
  40. package/dist/json.js +11 -0
  41. package/dist/json.js.map +1 -0
  42. package/dist/neo4j.d.ts +1 -0
  43. package/dist/neo4j.js +2046 -0
  44. package/dist/neo4j.js.map +1 -0
  45. package/dist/pajek.d.ts +1 -0
  46. package/dist/pajek.js +8 -0
  47. package/dist/pajek.js.map +1 -0
  48. package/dist/src/children.d.ts +134 -0
  49. package/dist/src/children.d.ts.map +1 -0
  50. package/dist/src/children.js +274 -0
  51. package/dist/src/children.js.map +1 -0
  52. package/dist/src/common/attributes.d.ts +229 -0
  53. package/dist/src/common/attributes.d.ts.map +1 -0
  54. package/dist/src/common/attributes.js +368 -0
  55. package/dist/src/common/attributes.js.map +1 -0
  56. package/dist/src/common/codes.d.ts +105 -0
  57. package/dist/src/common/codes.d.ts.map +1 -0
  58. package/dist/src/common/codes.js +107 -0
  59. package/dist/src/common/codes.js.map +1 -0
  60. package/dist/src/common/declared-types.d.ts +84 -0
  61. package/dist/src/common/declared-types.d.ts.map +1 -0
  62. package/dist/src/common/declared-types.js +326 -0
  63. package/dist/src/common/declared-types.js.map +1 -0
  64. package/dist/src/common/direction.d.ts +206 -0
  65. package/dist/src/common/direction.d.ts.map +1 -0
  66. package/dist/src/common/direction.js +370 -0
  67. package/dist/src/common/direction.js.map +1 -0
  68. package/dist/src/common/escape.d.ts +92 -0
  69. package/dist/src/common/escape.d.ts.map +1 -0
  70. package/dist/src/common/escape.js +212 -0
  71. package/dist/src/common/escape.js.map +1 -0
  72. package/dist/src/common/export.d.ts +249 -0
  73. package/dist/src/common/export.d.ts.map +1 -0
  74. package/dist/src/common/export.js +594 -0
  75. package/dist/src/common/export.js.map +1 -0
  76. package/dist/src/common/format.d.ts +59 -0
  77. package/dist/src/common/format.d.ts.map +1 -0
  78. package/dist/src/common/format.js +106 -0
  79. package/dist/src/common/format.js.map +1 -0
  80. package/dist/src/common/ids.d.ts +83 -0
  81. package/dist/src/common/ids.d.ts.map +1 -0
  82. package/dist/src/common/ids.js +158 -0
  83. package/dist/src/common/ids.js.map +1 -0
  84. package/dist/src/common/input.d.ts +100 -0
  85. package/dist/src/common/input.d.ts.map +1 -0
  86. package/dist/src/common/input.js +335 -0
  87. package/dist/src/common/input.js.map +1 -0
  88. package/dist/src/common/lists.d.ts +34 -0
  89. package/dist/src/common/lists.d.ts.map +1 -0
  90. package/dist/src/common/lists.js +185 -0
  91. package/dist/src/common/lists.js.map +1 -0
  92. package/dist/src/common/options.d.ts +108 -0
  93. package/dist/src/common/options.d.ts.map +1 -0
  94. package/dist/src/common/options.js +265 -0
  95. package/dist/src/common/options.js.map +1 -0
  96. package/dist/src/common/report.d.ts +187 -0
  97. package/dist/src/common/report.d.ts.map +1 -0
  98. package/dist/src/common/report.js +274 -0
  99. package/dist/src/common/report.js.map +1 -0
  100. package/dist/src/common/temporal.d.ts +71 -0
  101. package/dist/src/common/temporal.d.ts.map +1 -0
  102. package/dist/src/common/temporal.js +266 -0
  103. package/dist/src/common/temporal.js.map +1 -0
  104. package/dist/src/common/text.d.ts +104 -0
  105. package/dist/src/common/text.d.ts.map +1 -0
  106. package/dist/src/common/text.js +255 -0
  107. package/dist/src/common/text.js.map +1 -0
  108. package/dist/src/common/weights.d.ts +77 -0
  109. package/dist/src/common/weights.d.ts.map +1 -0
  110. package/dist/src/common/weights.js +156 -0
  111. package/dist/src/common/weights.js.map +1 -0
  112. package/dist/src/common/writer.d.ts +51 -0
  113. package/dist/src/common/writer.d.ts.map +1 -0
  114. package/dist/src/common/writer.js +108 -0
  115. package/dist/src/common/writer.js.map +1 -0
  116. package/dist/src/common/xml.d.ts +245 -0
  117. package/dist/src/common/xml.d.ts.map +1 -0
  118. package/dist/src/common/xml.js +942 -0
  119. package/dist/src/common/xml.js.map +1 -0
  120. package/dist/src/formats/csv/exporter.d.ts +70 -0
  121. package/dist/src/formats/csv/exporter.d.ts.map +1 -0
  122. package/dist/src/formats/csv/exporter.js +682 -0
  123. package/dist/src/formats/csv/exporter.js.map +1 -0
  124. package/dist/src/formats/csv/header.d.ts +66 -0
  125. package/dist/src/formats/csv/header.d.ts.map +1 -0
  126. package/dist/src/formats/csv/header.js +152 -0
  127. package/dist/src/formats/csv/header.js.map +1 -0
  128. package/dist/src/formats/csv/importer.d.ts +82 -0
  129. package/dist/src/formats/csv/importer.d.ts.map +1 -0
  130. package/dist/src/formats/csv/importer.js +849 -0
  131. package/dist/src/formats/csv/importer.js.map +1 -0
  132. package/dist/src/formats/csv/index.d.ts +60 -0
  133. package/dist/src/formats/csv/index.d.ts.map +1 -0
  134. package/dist/src/formats/csv/index.js +63 -0
  135. package/dist/src/formats/csv/index.js.map +1 -0
  136. package/dist/src/formats/csv/records.d.ts +188 -0
  137. package/dist/src/formats/csv/records.d.ts.map +1 -0
  138. package/dist/src/formats/csv/records.js +702 -0
  139. package/dist/src/formats/csv/records.js.map +1 -0
  140. package/dist/src/formats/csv/values.d.ts +105 -0
  141. package/dist/src/formats/csv/values.d.ts.map +1 -0
  142. package/dist/src/formats/csv/values.js +192 -0
  143. package/dist/src/formats/csv/values.js.map +1 -0
  144. package/dist/src/formats/dot/exporter.d.ts +52 -0
  145. package/dist/src/formats/dot/exporter.d.ts.map +1 -0
  146. package/dist/src/formats/dot/exporter.js +836 -0
  147. package/dist/src/formats/dot/exporter.js.map +1 -0
  148. package/dist/src/formats/dot/importer.d.ts +102 -0
  149. package/dist/src/formats/dot/importer.d.ts.map +1 -0
  150. package/dist/src/formats/dot/importer.js +1291 -0
  151. package/dist/src/formats/dot/importer.js.map +1 -0
  152. package/dist/src/formats/dot/index.d.ts +7 -0
  153. package/dist/src/formats/dot/index.d.ts.map +1 -0
  154. package/dist/src/formats/dot/index.js +7 -0
  155. package/dist/src/formats/dot/index.js.map +1 -0
  156. package/dist/src/formats/dot/names.d.ts +29 -0
  157. package/dist/src/formats/dot/names.d.ts.map +1 -0
  158. package/dist/src/formats/dot/names.js +28 -0
  159. package/dist/src/formats/dot/names.js.map +1 -0
  160. package/dist/src/formats/dot/tokenizer.d.ts +114 -0
  161. package/dist/src/formats/dot/tokenizer.d.ts.map +1 -0
  162. package/dist/src/formats/dot/tokenizer.js +341 -0
  163. package/dist/src/formats/dot/tokenizer.js.map +1 -0
  164. package/dist/src/formats/gexf/exporter.d.ts +56 -0
  165. package/dist/src/formats/gexf/exporter.d.ts.map +1 -0
  166. package/dist/src/formats/gexf/exporter.js +1395 -0
  167. package/dist/src/formats/gexf/exporter.js.map +1 -0
  168. package/dist/src/formats/gexf/importer.d.ts +73 -0
  169. package/dist/src/formats/gexf/importer.d.ts.map +1 -0
  170. package/dist/src/formats/gexf/importer.js +1880 -0
  171. package/dist/src/formats/gexf/importer.js.map +1 -0
  172. package/dist/src/formats/gexf/index.d.ts +96 -0
  173. package/dist/src/formats/gexf/index.d.ts.map +1 -0
  174. package/dist/src/formats/gexf/index.js +97 -0
  175. package/dist/src/formats/gexf/index.js.map +1 -0
  176. package/dist/src/formats/gexf/schema.d.ts +135 -0
  177. package/dist/src/formats/gexf/schema.d.ts.map +1 -0
  178. package/dist/src/formats/gexf/schema.js +323 -0
  179. package/dist/src/formats/gexf/schema.js.map +1 -0
  180. package/dist/src/formats/gml/exporter.d.ts +69 -0
  181. package/dist/src/formats/gml/exporter.d.ts.map +1 -0
  182. package/dist/src/formats/gml/exporter.js +1093 -0
  183. package/dist/src/formats/gml/exporter.js.map +1 -0
  184. package/dist/src/formats/gml/importer.d.ts +66 -0
  185. package/dist/src/formats/gml/importer.d.ts.map +1 -0
  186. package/dist/src/formats/gml/importer.js +1331 -0
  187. package/dist/src/formats/gml/importer.js.map +1 -0
  188. package/dist/src/formats/gml/index.d.ts +85 -0
  189. package/dist/src/formats/gml/index.d.ts.map +1 -0
  190. package/dist/src/formats/gml/index.js +88 -0
  191. package/dist/src/formats/gml/index.js.map +1 -0
  192. package/dist/src/formats/gml/syntax.d.ts +186 -0
  193. package/dist/src/formats/gml/syntax.d.ts.map +1 -0
  194. package/dist/src/formats/gml/syntax.js +467 -0
  195. package/dist/src/formats/gml/syntax.js.map +1 -0
  196. package/dist/src/formats/graphml/constants.d.ts +169 -0
  197. package/dist/src/formats/graphml/constants.d.ts.map +1 -0
  198. package/dist/src/formats/graphml/constants.js +165 -0
  199. package/dist/src/formats/graphml/constants.js.map +1 -0
  200. package/dist/src/formats/graphml/exporter.d.ts +34 -0
  201. package/dist/src/formats/graphml/exporter.d.ts.map +1 -0
  202. package/dist/src/formats/graphml/exporter.js +1176 -0
  203. package/dist/src/formats/graphml/exporter.js.map +1 -0
  204. package/dist/src/formats/graphml/importer.d.ts +31 -0
  205. package/dist/src/formats/graphml/importer.d.ts.map +1 -0
  206. package/dist/src/formats/graphml/importer.js +1607 -0
  207. package/dist/src/formats/graphml/importer.js.map +1 -0
  208. package/dist/src/formats/graphml/index.d.ts +8 -0
  209. package/dist/src/formats/graphml/index.d.ts.map +1 -0
  210. package/dist/src/formats/graphml/index.js +8 -0
  211. package/dist/src/formats/graphml/index.js.map +1 -0
  212. package/dist/src/formats/graphml/tree.d.ts +72 -0
  213. package/dist/src/formats/graphml/tree.d.ts.map +1 -0
  214. package/dist/src/formats/graphml/tree.js +290 -0
  215. package/dist/src/formats/graphml/tree.js.map +1 -0
  216. package/dist/src/formats/json/dialect.d.ts +125 -0
  217. package/dist/src/formats/json/dialect.d.ts.map +1 -0
  218. package/dist/src/formats/json/dialect.js +262 -0
  219. package/dist/src/formats/json/dialect.js.map +1 -0
  220. package/dist/src/formats/json/exporter.d.ts +89 -0
  221. package/dist/src/formats/json/exporter.d.ts.map +1 -0
  222. package/dist/src/formats/json/exporter.js +1358 -0
  223. package/dist/src/formats/json/exporter.js.map +1 -0
  224. package/dist/src/formats/json/importer.d.ts +108 -0
  225. package/dist/src/formats/json/importer.d.ts.map +1 -0
  226. package/dist/src/formats/json/importer.js +1838 -0
  227. package/dist/src/formats/json/importer.js.map +1 -0
  228. package/dist/src/formats/json/index.d.ts +8 -0
  229. package/dist/src/formats/json/index.d.ts.map +1 -0
  230. package/dist/src/formats/json/index.js +8 -0
  231. package/dist/src/formats/json/index.js.map +1 -0
  232. package/dist/src/formats/neo4j/exporter.d.ts +68 -0
  233. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -0
  234. package/dist/src/formats/neo4j/exporter.js +1055 -0
  235. package/dist/src/formats/neo4j/exporter.js.map +1 -0
  236. package/dist/src/formats/neo4j/header.d.ts +52 -0
  237. package/dist/src/formats/neo4j/header.d.ts.map +1 -0
  238. package/dist/src/formats/neo4j/header.js +131 -0
  239. package/dist/src/formats/neo4j/header.js.map +1 -0
  240. package/dist/src/formats/neo4j/importer.d.ts +73 -0
  241. package/dist/src/formats/neo4j/importer.d.ts.map +1 -0
  242. package/dist/src/formats/neo4j/importer.js +932 -0
  243. package/dist/src/formats/neo4j/importer.js.map +1 -0
  244. package/dist/src/formats/neo4j/index.d.ts +79 -0
  245. package/dist/src/formats/neo4j/index.d.ts.map +1 -0
  246. package/dist/src/formats/neo4j/index.js +83 -0
  247. package/dist/src/formats/neo4j/index.js.map +1 -0
  248. package/dist/src/formats/pajek/exporter.d.ts +58 -0
  249. package/dist/src/formats/pajek/exporter.d.ts.map +1 -0
  250. package/dist/src/formats/pajek/exporter.js +825 -0
  251. package/dist/src/formats/pajek/exporter.js.map +1 -0
  252. package/dist/src/formats/pajek/importer.d.ts +88 -0
  253. package/dist/src/formats/pajek/importer.d.ts.map +1 -0
  254. package/dist/src/formats/pajek/importer.js +1047 -0
  255. package/dist/src/formats/pajek/importer.js.map +1 -0
  256. package/dist/src/formats/pajek/index.d.ts +7 -0
  257. package/dist/src/formats/pajek/index.d.ts.map +1 -0
  258. package/dist/src/formats/pajek/index.js +7 -0
  259. package/dist/src/formats/pajek/index.js.map +1 -0
  260. package/dist/src/formats/pajek/syntax.d.ts +112 -0
  261. package/dist/src/formats/pajek/syntax.d.ts.map +1 -0
  262. package/dist/src/formats/pajek/syntax.js +269 -0
  263. package/dist/src/formats/pajek/syntax.js.map +1 -0
  264. package/dist/src/index.d.ts +35 -0
  265. package/dist/src/index.d.ts.map +1 -0
  266. package/dist/src/index.js +39 -0
  267. package/dist/src/index.js.map +1 -0
  268. package/dist/src/registry.d.ts +207 -0
  269. package/dist/src/registry.d.ts.map +1 -0
  270. package/dist/src/registry.js +481 -0
  271. package/dist/src/registry.js.map +1 -0
  272. package/dist/src/sniff.d.ts +104 -0
  273. package/dist/src/sniff.d.ts.map +1 -0
  274. package/dist/src/sniff.js +357 -0
  275. package/dist/src/sniff.js.map +1 -0
  276. package/dist/src/types.d.ts +238 -0
  277. package/dist/src/types.d.ts.map +1 -0
  278. package/dist/src/types.js +29 -0
  279. package/dist/src/types.js.map +1 -0
  280. package/dist/tsconfig.build.tsbuildinfo +1 -0
  281. package/package.json +122 -7
  282. package/src/children.ts +335 -0
  283. package/src/common/attributes.ts +520 -0
  284. package/src/common/codes.ts +153 -0
  285. package/src/common/declared-types.ts +374 -0
  286. package/src/common/direction.ts +518 -0
  287. package/src/common/escape.ts +231 -0
  288. package/src/common/export.ts +817 -0
  289. package/src/common/format.ts +111 -0
  290. package/src/common/ids.ts +176 -0
  291. package/src/common/input.ts +378 -0
  292. package/src/common/lists.ts +196 -0
  293. package/src/common/options.ts +377 -0
  294. package/src/common/report.ts +352 -0
  295. package/src/common/temporal.ts +302 -0
  296. package/src/common/text.ts +294 -0
  297. package/src/common/weights.ts +202 -0
  298. package/src/common/writer.ts +123 -0
  299. package/src/common/xml.ts +1053 -0
  300. package/src/formats/csv/exporter.ts +894 -0
  301. package/src/formats/csv/header.ts +172 -0
  302. package/src/formats/csv/importer.ts +1104 -0
  303. package/src/formats/csv/index.ts +88 -0
  304. package/src/formats/csv/records.ts +813 -0
  305. package/src/formats/csv/values.ts +224 -0
  306. package/src/formats/dot/exporter.ts +1014 -0
  307. package/src/formats/dot/importer.ts +1549 -0
  308. package/src/formats/dot/index.ts +7 -0
  309. package/src/formats/dot/names.ts +40 -0
  310. package/src/formats/dot/tokenizer.ts +384 -0
  311. package/src/formats/gexf/exporter.ts +1696 -0
  312. package/src/formats/gexf/importer.ts +2333 -0
  313. package/src/formats/gexf/index.ts +142 -0
  314. package/src/formats/gexf/schema.ts +361 -0
  315. package/src/formats/gml/exporter.ts +1404 -0
  316. package/src/formats/gml/importer.ts +1591 -0
  317. package/src/formats/gml/index.ts +128 -0
  318. package/src/formats/gml/syntax.ts +545 -0
  319. package/src/formats/graphml/constants.ts +225 -0
  320. package/src/formats/graphml/exporter.ts +1458 -0
  321. package/src/formats/graphml/importer.ts +2027 -0
  322. package/src/formats/graphml/index.ts +8 -0
  323. package/src/formats/graphml/tree.ts +318 -0
  324. package/src/formats/json/dialect.ts +317 -0
  325. package/src/formats/json/exporter.ts +1616 -0
  326. package/src/formats/json/importer.ts +2271 -0
  327. package/src/formats/json/index.ts +8 -0
  328. package/src/formats/neo4j/exporter.ts +1287 -0
  329. package/src/formats/neo4j/header.ts +156 -0
  330. package/src/formats/neo4j/importer.ts +1220 -0
  331. package/src/formats/neo4j/index.ts +116 -0
  332. package/src/formats/pajek/exporter.ts +1000 -0
  333. package/src/formats/pajek/importer.ts +1311 -0
  334. package/src/formats/pajek/index.ts +7 -0
  335. package/src/formats/pajek/syntax.ts +307 -0
  336. package/src/index.ts +244 -0
  337. package/src/registry.ts +617 -0
  338. package/src/sniff.ts +397 -0
  339. package/src/types.ts +262 -0
@@ -0,0 +1,104 @@
1
+ /**
2
+ * The fixed lexical grammar of design section 5.1 for untyped text sources (CSV cells, GML
3
+ * values, DOT strings, Pajek tokens), reproduced from the core's reference implementation so the
4
+ * two agree (invariant I15). Text importers parse each cell with parseTextCell() and push the JS
5
+ * value; the sink's per-column inference then widens `bool -> i32 -> f64 -> string` and never per
6
+ * cell, so a column that saw `1` and then `"01"` becomes string for all rows.
7
+ *
8
+ * - `bool` is exactly `true` / `false` (case-sensitive);
9
+ * - `i32` is `/^-?(0|[1-9][0-9]*)$/` within `[-2^31, 2^31)`; `0` / `1` are i32, never bool;
10
+ * - `f64` is a decimal or exponent literal accepted by `Number()` that is not empty, not
11
+ * whitespace, not `Infinity` / `NaN`, not a hex / octal / binary form, has no leading zeros in
12
+ * its integer part, and whose value is finite (an integer literal outside i32 range is f64);
13
+ * - everything else is `string`.
14
+ */
15
+ import { type ColumnHandle, type GraphSink } from "@graphty/graph-format";
16
+ import { type ImportReportBuilder } from "./report.js";
17
+ /**
18
+ * The dtype a text cell parses as under the design section 5.1 grammar.
19
+ * Consumed by the per-format importers and exporters under src/formats.
20
+ * @public
21
+ */
22
+ export type TextDtype = "bool" | "i32" | "f64" | "string";
23
+ /**
24
+ * Classify one text cell by the fixed grammar.
25
+ * @param text - the cell text, exactly as read (no trimming)
26
+ * @returns bool, i32, f64 or string
27
+ */
28
+ export declare function inferTextDtype(text: string): TextDtype;
29
+ /**
30
+ * Parse one text cell into the JS value its grammar class implies: a boolean for bool, a number for
31
+ * i32 / f64, the text itself for string. The sink infers the column dtype from the value.
32
+ * @param text - the cell text, exactly as read
33
+ * @returns the value
34
+ */
35
+ export declare function parseTextCell(text: string): boolean | number | string;
36
+ /**
37
+ * Whether a text cell is a number under the f64 grammar (an i32 or f64 literal).
38
+ * @param text - the cell text
39
+ * @returns true when parseTextCell(text) returns a number
40
+ */
41
+ export declare function isNumericText(text: string): boolean;
42
+ /**
43
+ * The inferred-column writer of the untyped text formats (CSV, DOT, Pajek; design section 5.1):
44
+ * parses every cell by the fixed grammar and pushes the scalar, and keeps the COLUMN's dtype the
45
+ * one the grammar implies rather than the one the values happen to imply:
46
+ *
47
+ * - a column whose cells are all `2.0`-style f64 text is widened to f64 through the sink's
48
+ * widening call even though every value is integral (the values alone would infer i32);
49
+ * - a numeric cell whose text is not the canonical spelling of its value (`1e5`, `-0`, `1.0`) is
50
+ * remembered, and when a later cell widens the column to string the original texts are written
51
+ * back, so the lexical form is never rewritten by the widening.
52
+ *
53
+ * A sink without the optional widening call keeps the value-inferred dtype and the writer records
54
+ * one W_WIDENING_UNSUPPORTED warning per column.
55
+ * Consumed by the per-format importers under src/formats.
56
+ * @public
57
+ */
58
+ export declare class TextCellWriter {
59
+ /** The column name in the sink. */
60
+ readonly name: string;
61
+ private readonly domain;
62
+ private readonly sink;
63
+ private readonly report;
64
+ private handle;
65
+ /** The widest text dtype seen (the column's dtype under the 5.1 grammar). */
66
+ private textDtype;
67
+ /** The widest dtype the pushed values imply (what the sink inferred on its own). */
68
+ private valueDtype;
69
+ private readonly keptRows;
70
+ private readonly keptTexts;
71
+ /**
72
+ * Create a writer; the column is declared by the sink's inference on the first write.
73
+ * @param name - the column name
74
+ * @param domain - node or edge
75
+ * @param sink - the sink
76
+ * @param report - the report the widening warning is recorded in
77
+ */
78
+ constructor(name: string, domain: "node" | "edge", sink: GraphSink, report: ImportReportBuilder);
79
+ /**
80
+ * The column handle once the first cell was written.
81
+ * @returns the handle, or INVALID_INDEX before the first write
82
+ */
83
+ get column(): ColumnHandle;
84
+ /**
85
+ * Write one cell text.
86
+ * @param row - the node or edge index
87
+ * @param text - the cell text, exactly as read
88
+ */
89
+ write(row: number, text: string): void;
90
+ /**
91
+ * Write a value (the parsed scalar, or a text into a widened column).
92
+ * @param row - the row
93
+ * @param value - the value
94
+ */
95
+ private set;
96
+ /**
97
+ * Widen the column to the dtype the text grammar implies, through the sink's optional call.
98
+ * @param dtype - the dtype
99
+ */
100
+ private widen;
101
+ }
102
+ /** Issue code: the sink has no widening call, so a text column keeps the dtype its values imply. */
103
+ export declare const WIDENING_UNSUPPORTED_CODE = "W_WIDENING_UNSUPPORTED";
104
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/common/text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAoB,KAAK,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAE3G,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAOvD;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE1D;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAetD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAYrE;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGnD;AAmCD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,cAAc;IACvB,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IAEzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IAEjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAE7C,OAAO,CAAC,MAAM,CAA+C;IAE7D,6EAA6E;IAC7E,OAAO,CAAC,SAAS,CAA0B;IAE3C,oFAAoF;IACpF,OAAO,CAAC,UAAU,CAA0B;IAE5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IAEzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAE1C;;;;;;OAMG;gBACS,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB;IAO/F;;;OAGG;IACH,IAAI,MAAM,IAAI,YAAY,CAEzB;IAED;;;;OAIG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAoCtC;;;;OAIG;IACH,OAAO,CAAC,GAAG;IAkBX;;;OAGG;IACH,OAAO,CAAC,KAAK;CA6BhB;AAED,oGAAoG;AACpG,eAAO,MAAM,yBAAyB,2BAA2B,CAAC"}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * The fixed lexical grammar of design section 5.1 for untyped text sources (CSV cells, GML
3
+ * values, DOT strings, Pajek tokens), reproduced from the core's reference implementation so the
4
+ * two agree (invariant I15). Text importers parse each cell with parseTextCell() and push the JS
5
+ * value; the sink's per-column inference then widens `bool -> i32 -> f64 -> string` and never per
6
+ * cell, so a column that saw `1` and then `"01"` becomes string for all rows.
7
+ *
8
+ * - `bool` is exactly `true` / `false` (case-sensitive);
9
+ * - `i32` is `/^-?(0|[1-9][0-9]*)$/` within `[-2^31, 2^31)`; `0` / `1` are i32, never bool;
10
+ * - `f64` is a decimal or exponent literal accepted by `Number()` that is not empty, not
11
+ * whitespace, not `Infinity` / `NaN`, not a hex / octal / binary form, has no leading zeros in
12
+ * its integer part, and whose value is finite (an integer literal outside i32 range is f64);
13
+ * - everything else is `string`.
14
+ */
15
+ import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
16
+ const I32_TEXT = /^-?(0|[1-9][0-9]*)$/;
17
+ const F64_TEXT = /^[+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([eE][+-]?[0-9]+)?$/;
18
+ const I32_MIN = -2147483648;
19
+ const I32_MAX = 2147483647;
20
+ /**
21
+ * Classify one text cell by the fixed grammar.
22
+ * @param text - the cell text, exactly as read (no trimming)
23
+ * @returns bool, i32, f64 or string
24
+ */
25
+ export function inferTextDtype(text) {
26
+ if (text === "true" || text === "false") {
27
+ return "bool";
28
+ }
29
+ if (I32_TEXT.test(text)) {
30
+ const n = Number(text);
31
+ if (n >= I32_MIN && n <= I32_MAX) {
32
+ return "i32";
33
+ }
34
+ return Number.isFinite(n) ? "f64" : "string";
35
+ }
36
+ if (F64_TEXT.test(text) && Number.isFinite(Number(text))) {
37
+ return "f64";
38
+ }
39
+ return "string";
40
+ }
41
+ /**
42
+ * Parse one text cell into the JS value its grammar class implies: a boolean for bool, a number for
43
+ * i32 / f64, the text itself for string. The sink infers the column dtype from the value.
44
+ * @param text - the cell text, exactly as read
45
+ * @returns the value
46
+ */
47
+ export function parseTextCell(text) {
48
+ switch (inferTextDtype(text)) {
49
+ case "bool":
50
+ return text === "true";
51
+ case "i32":
52
+ case "f64":
53
+ return Number(text);
54
+ case "string":
55
+ return text;
56
+ default:
57
+ return text;
58
+ }
59
+ }
60
+ /**
61
+ * Whether a text cell is a number under the f64 grammar (an i32 or f64 literal).
62
+ * @param text - the cell text
63
+ * @returns true when parseTextCell(text) returns a number
64
+ */
65
+ export function isNumericText(text) {
66
+ const dtype = inferTextDtype(text);
67
+ return dtype === "i32" || dtype === "f64";
68
+ }
69
+ /**
70
+ * Whether a numeric cell text is the canonical spelling of its value (`String(value) === text`),
71
+ * so that the sink's own re-formatting of the value would reproduce it.
72
+ * @param text - the cell text
73
+ * @param value - the parsed value
74
+ * @returns true when the lexical form survives a widening to string
75
+ */
76
+ function isCanonicalNumberText(text, value) {
77
+ return String(value) === text;
78
+ }
79
+ /**
80
+ * The widening rank of a text dtype in the design section 5.1 order.
81
+ * @param dtype - the text dtype
82
+ * @returns 0 for bool, 1 for i32, 2 for f64, 3 for string
83
+ */
84
+ function textDtypeRank(dtype) {
85
+ switch (dtype) {
86
+ case "bool":
87
+ return 0;
88
+ case "i32":
89
+ return 1;
90
+ case "f64":
91
+ return 2;
92
+ case "string":
93
+ return 3;
94
+ default: {
95
+ const name = dtype;
96
+ throw new GraphFormatError("E_UNSUPPORTED", `unknown text dtype ${name}`, { dtype: name });
97
+ }
98
+ }
99
+ }
100
+ /**
101
+ * The inferred-column writer of the untyped text formats (CSV, DOT, Pajek; design section 5.1):
102
+ * parses every cell by the fixed grammar and pushes the scalar, and keeps the COLUMN's dtype the
103
+ * one the grammar implies rather than the one the values happen to imply:
104
+ *
105
+ * - a column whose cells are all `2.0`-style f64 text is widened to f64 through the sink's
106
+ * widening call even though every value is integral (the values alone would infer i32);
107
+ * - a numeric cell whose text is not the canonical spelling of its value (`1e5`, `-0`, `1.0`) is
108
+ * remembered, and when a later cell widens the column to string the original texts are written
109
+ * back, so the lexical form is never rewritten by the widening.
110
+ *
111
+ * A sink without the optional widening call keeps the value-inferred dtype and the writer records
112
+ * one W_WIDENING_UNSUPPORTED warning per column.
113
+ * Consumed by the per-format importers under src/formats.
114
+ * @public
115
+ */
116
+ export class TextCellWriter {
117
+ /**
118
+ * Create a writer; the column is declared by the sink's inference on the first write.
119
+ * @param name - the column name
120
+ * @param domain - node or edge
121
+ * @param sink - the sink
122
+ * @param report - the report the widening warning is recorded in
123
+ */
124
+ constructor(name, domain, sink, report) {
125
+ this.handle = INVALID_INDEX;
126
+ /** The widest text dtype seen (the column's dtype under the 5.1 grammar). */
127
+ this.textDtype = null;
128
+ /** The widest dtype the pushed values imply (what the sink inferred on its own). */
129
+ this.valueDtype = null;
130
+ this.keptRows = [];
131
+ this.keptTexts = [];
132
+ this.name = name;
133
+ this.domain = domain;
134
+ this.sink = sink;
135
+ this.report = report;
136
+ }
137
+ /**
138
+ * The column handle once the first cell was written.
139
+ * @returns the handle, or INVALID_INDEX before the first write
140
+ */
141
+ get column() {
142
+ return this.handle;
143
+ }
144
+ /**
145
+ * Write one cell text.
146
+ * @param row - the node or edge index
147
+ * @param text - the cell text, exactly as read
148
+ */
149
+ write(row, text) {
150
+ const kind = inferTextDtype(text);
151
+ const value = parseTextCell(text);
152
+ const wasString = this.textDtype === "string";
153
+ const textDtype = this.textDtype === null || textDtypeRank(kind) > textDtypeRank(this.textDtype) ? kind : this.textDtype;
154
+ // a string column keeps every cell's lexical form; a numeric text is never re-spelled. The
155
+ // sink may refuse the value (a declared column of another dtype): the state advances only
156
+ // once the cell is written, so a refused cell leaves the writer as it was.
157
+ this.set(row, textDtype === "string" ? text : value);
158
+ this.textDtype = textDtype;
159
+ const valueKind = kindOfValue(value);
160
+ if (this.valueDtype === null || textDtypeRank(valueKind) > textDtypeRank(this.valueDtype)) {
161
+ this.valueDtype = valueKind;
162
+ }
163
+ if (this.textDtype === "string") {
164
+ if (!wasString && this.keptRows.length > 0) {
165
+ // the sink just widened the column to string from the values; restore the texts
166
+ // whose lexical form the values did not carry
167
+ for (let i = 0; i < this.keptRows.length; i++) {
168
+ this.set(this.keptRows[i], this.keptTexts[i]);
169
+ }
170
+ this.keptRows.length = 0;
171
+ this.keptTexts.length = 0;
172
+ }
173
+ return;
174
+ }
175
+ if (typeof value === "number" && !isCanonicalNumberText(text, value)) {
176
+ this.keptRows.push(row);
177
+ this.keptTexts.push(text);
178
+ }
179
+ if (this.textDtype === "f64" && this.valueDtype !== "f64") {
180
+ this.widen("f64");
181
+ }
182
+ }
183
+ /**
184
+ * Write a value (the parsed scalar, or a text into a widened column).
185
+ * @param row - the row
186
+ * @param value - the value
187
+ */
188
+ set(row, value) {
189
+ if (this.handle === INVALID_INDEX) {
190
+ if (this.domain === "node") {
191
+ this.sink.setNodeValue(this.name, row, value);
192
+ this.handle = this.sink.nodeColumn(this.name);
193
+ }
194
+ else {
195
+ this.sink.setEdgeValue(this.name, row, value);
196
+ this.handle = this.sink.edgeColumn(this.name);
197
+ }
198
+ return;
199
+ }
200
+ if (this.domain === "node") {
201
+ this.sink.setNodeValue(this.handle, row, value);
202
+ }
203
+ else {
204
+ this.sink.setEdgeValue(this.handle, row, value);
205
+ }
206
+ }
207
+ /**
208
+ * Widen the column to the dtype the text grammar implies, through the sink's optional call.
209
+ * @param dtype - the dtype
210
+ */
211
+ widen(dtype) {
212
+ const { sink } = this;
213
+ const supported = this.domain === "node" ? sink.widenNodeColumn !== undefined : sink.widenEdgeColumn !== undefined;
214
+ if (!supported) {
215
+ this.report.warnOnce("coercion", WIDENING_UNSUPPORTED_CODE, `column "${this.name}" holds ${dtype} text but the sink cannot widen an inferred column; it keeps the value-inferred dtype`, { element: this.name });
216
+ this.valueDtype = dtype;
217
+ return;
218
+ }
219
+ try {
220
+ if (this.domain === "node") {
221
+ sink.widenNodeColumn?.(this.handle, dtype);
222
+ }
223
+ else {
224
+ sink.widenEdgeColumn?.(this.handle, dtype);
225
+ }
226
+ this.valueDtype = dtype;
227
+ }
228
+ catch (err) {
229
+ if (!(err instanceof GraphFormatError) || err.code !== "E_COLUMN_TYPE") {
230
+ throw err;
231
+ }
232
+ // a caller's declared column of the name: its dtype stands
233
+ this.valueDtype = dtype;
234
+ }
235
+ }
236
+ }
237
+ /** Issue code: the sink has no widening call, so a text column keeps the dtype its values imply. */
238
+ export const WIDENING_UNSUPPORTED_CODE = "W_WIDENING_UNSUPPORTED";
239
+ /**
240
+ * The text dtype a parsed cell value implies on its own (what the sink's inference sees).
241
+ * @param value - the parsed value
242
+ * @returns the dtype
243
+ */
244
+ function kindOfValue(value) {
245
+ if (typeof value === "boolean") {
246
+ return "bool";
247
+ }
248
+ if (typeof value === "string") {
249
+ return "string";
250
+ }
251
+ return Number.isInteger(value) && value >= -2147483648 && value <= 2147483647 && !Object.is(value, -0)
252
+ ? "i32"
253
+ : "f64";
254
+ }
255
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/common/text.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Weight resolution shared by every importer (design sections 3.7 and 8.4): which source field is
3
+ * THE weight (`weightFrom`, per-format default, null = unweighted), how its text or JSON value
4
+ * becomes the number passed to `addEdge`, and the E_INVALID_WEIGHT boundary.
5
+ *
6
+ * An edge whose weight field is absent or blank is pushed WITHOUT a weight argument, never with an
7
+ * explicit 1: the builder's weightSet bitmap then records that the weight was defaulted, and the
8
+ * exporter re-emits no weight for it (decision D-WSET). NaN and non-numeric text are
9
+ * E_INVALID_WEIGHT before the sink is touched, so the importer records the issue and skips the edge
10
+ * with the sink unchanged; Infinity and negative values are legal weights (design section 3.7).
11
+ */
12
+ import { type GraphSnapshot } from "@graphty/graph-format";
13
+ /** The weight of an edge added without one (design section 3.7). */
14
+ export declare const DEFAULT_WEIGHT = 1;
15
+ /**
16
+ * Whether a source field is the weight field under the resolved `weightFrom` option.
17
+ * @param name - the field name (attribute title, CSV header, JSON key)
18
+ * @param weightFrom - the resolved option; null means unweighted
19
+ * @returns true when the field is THE weight
20
+ */
21
+ export declare function isWeightField(name: string, weightFrom: string | null): boolean;
22
+ /**
23
+ * The weight argument of addEdge from a text cell: undefined for a blank cell (the weight is
24
+ * omitted), the number otherwise.
25
+ * @param text - the cell text
26
+ * @returns the weight, or undefined when blank; E_INVALID_WEIGHT for NaN or non-numeric text
27
+ */
28
+ export declare function parseWeightText(text: string): number | undefined;
29
+ /**
30
+ * The weight argument of addEdge from a typed value (JSON, a record field): undefined for null /
31
+ * undefined, the number for a finite or infinite number, the parsed number for numeric text.
32
+ * @param value - the field value
33
+ * @returns the weight, or undefined when absent; E_INVALID_WEIGHT for NaN, a boolean, an object or non-numeric text
34
+ */
35
+ export declare function weightFromValue(value: unknown): number | undefined;
36
+ /**
37
+ * The explicit weights of a snapshot for exporters (design sections 3.7 and 8.5): the weight
38
+ * role column when present (its validity says which edges had an explicit weight, its dtype how
39
+ * the value is written), else `edgeList().weights` as f32 for every edge of a weighted snapshot;
40
+ * nothing for an unweighted one. One implementation for every exporter.
41
+ * Consumed by the per-format exporters under src/formats.
42
+ * @public
43
+ */
44
+ export interface ExplicitWeights {
45
+ /** Whether any edge can have an explicit weight (the snapshot is weighted). */
46
+ readonly weighted: boolean;
47
+ /** The dtype the values are read from: the shadow column's, or f32 for the arc array. */
48
+ readonly dtype: "f32" | "f64";
49
+ /**
50
+ * Whether an edge's weight was explicit in the source.
51
+ * @param e - the logical edge index
52
+ * @returns true when the exporter must write it
53
+ */
54
+ isExplicit(e: number): boolean;
55
+ /**
56
+ * The weight value of an edge (meaningful when explicit).
57
+ * @param e - the logical edge index
58
+ * @returns the value
59
+ */
60
+ value(e: number): number;
61
+ /**
62
+ * The weight text of an edge: the shortest round-tripping decimal for its dtype, or the
63
+ * integer digits when `integral` is requested and the value is an integer; null when the
64
+ * weight was defaulted.
65
+ * @param e - the logical edge index
66
+ * @param integral - write an integral value without a decimal part (formats declaring an int weight)
67
+ * @returns the text, or null
68
+ */
69
+ text(e: number, integral?: boolean): string | null;
70
+ }
71
+ /**
72
+ * Build the explicit-weight view of a snapshot.
73
+ * @param snapshot - the snapshot
74
+ * @returns the view
75
+ */
76
+ export declare function explicitWeights(snapshot: GraphSnapshot): ExplicitWeights;
77
+ //# sourceMappingURL=weights.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weights.d.ts","sourceRoot":"","sources":["../../../src/common/weights.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAiC,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAK1F,oEAAoE;AACpE,eAAO,MAAM,cAAc,IAAI,CAAC;AAEhC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAE9E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAehE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAclE;AA4BD;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,yFAAyF;IACzF,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC;IAC9B;;;;OAIG;IACH,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B;;;;OAIG;IACH,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;CACtD;AAqBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,eAAe,CAwCxE"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Weight resolution shared by every importer (design sections 3.7 and 8.4): which source field is
3
+ * THE weight (`weightFrom`, per-format default, null = unweighted), how its text or JSON value
4
+ * becomes the number passed to `addEdge`, and the E_INVALID_WEIGHT boundary.
5
+ *
6
+ * An edge whose weight field is absent or blank is pushed WITHOUT a weight argument, never with an
7
+ * explicit 1: the builder's weightSet bitmap then records that the weight was defaulted, and the
8
+ * exporter re-emits no weight for it (decision D-WSET). NaN and non-numeric text are
9
+ * E_INVALID_WEIGHT before the sink is touched, so the importer records the issue and skips the edge
10
+ * with the sink unchanged; Infinity and negative values are legal weights (design section 3.7).
11
+ */
12
+ import { GraphFormatError } from "@graphty/graph-format";
13
+ import { parseDecimalText } from "./declared-types.js";
14
+ import { formatF32, formatF64, formatInteger } from "./format.js";
15
+ /** The weight of an edge added without one (design section 3.7). */
16
+ export const DEFAULT_WEIGHT = 1;
17
+ /**
18
+ * Whether a source field is the weight field under the resolved `weightFrom` option.
19
+ * @param name - the field name (attribute title, CSV header, JSON key)
20
+ * @param weightFrom - the resolved option; null means unweighted
21
+ * @returns true when the field is THE weight
22
+ */
23
+ export function isWeightField(name, weightFrom) {
24
+ return weightFrom !== null && name === weightFrom;
25
+ }
26
+ /**
27
+ * The weight argument of addEdge from a text cell: undefined for a blank cell (the weight is
28
+ * omitted), the number otherwise.
29
+ * @param text - the cell text
30
+ * @returns the weight, or undefined when blank; E_INVALID_WEIGHT for NaN or non-numeric text
31
+ */
32
+ export function parseWeightText(text) {
33
+ const trimmed = text.trim();
34
+ if (trimmed.length === 0) {
35
+ return undefined;
36
+ }
37
+ let value;
38
+ try {
39
+ value = parseDecimalText(trimmed);
40
+ }
41
+ catch (err) {
42
+ throw invalidWeight(text, err);
43
+ }
44
+ if (Number.isNaN(value)) {
45
+ throw invalidWeight(text, null);
46
+ }
47
+ return value;
48
+ }
49
+ /**
50
+ * The weight argument of addEdge from a typed value (JSON, a record field): undefined for null /
51
+ * undefined, the number for a finite or infinite number, the parsed number for numeric text.
52
+ * @param value - the field value
53
+ * @returns the weight, or undefined when absent; E_INVALID_WEIGHT for NaN, a boolean, an object or non-numeric text
54
+ */
55
+ export function weightFromValue(value) {
56
+ if (value === undefined || value === null) {
57
+ return undefined;
58
+ }
59
+ if (typeof value === "number") {
60
+ if (Number.isNaN(value)) {
61
+ throw invalidWeight(value, null);
62
+ }
63
+ return value;
64
+ }
65
+ if (typeof value === "string") {
66
+ return parseWeightText(value);
67
+ }
68
+ throw invalidWeight(value, null);
69
+ }
70
+ /**
71
+ * The E_INVALID_WEIGHT error of a rejected value.
72
+ * @param value - the rejected value
73
+ * @param cause - the parse error, or null
74
+ * @returns the error
75
+ */
76
+ function invalidWeight(value, cause) {
77
+ let shown;
78
+ switch (typeof value) {
79
+ case "string":
80
+ shown = JSON.stringify(value);
81
+ break;
82
+ case "number":
83
+ shown = String(value);
84
+ break;
85
+ default:
86
+ shown = typeof value;
87
+ }
88
+ return new GraphFormatError("E_INVALID_WEIGHT", `invalid edge weight ${shown}`, {
89
+ value: typeof value === "object" ? typeof value : value,
90
+ cause: cause instanceof Error ? cause.message : null,
91
+ });
92
+ }
93
+ /** The dtypes a weight role column may have (an integer column declared by a caller included). */
94
+ const NUMERIC_DTYPES = new Set(["f32", "f64", "i32", "u32", "u8"]);
95
+ /**
96
+ * The shortest round-tripping text of a weight by the shadow column's dtype.
97
+ * @param dtype - the shadow column's dtype
98
+ * @returns the formatter
99
+ */
100
+ function weightFormatter(dtype) {
101
+ switch (dtype) {
102
+ case "f32":
103
+ return formatF32;
104
+ case "f64":
105
+ return formatF64;
106
+ default:
107
+ return formatInteger;
108
+ }
109
+ }
110
+ /**
111
+ * Build the explicit-weight view of a snapshot.
112
+ * @param snapshot - the snapshot
113
+ * @returns the view
114
+ */
115
+ export function explicitWeights(snapshot) {
116
+ const shadowColumn = snapshot.edges.byRole("weight");
117
+ const shadow = shadowColumn !== null && NUMERIC_DTYPES.has(shadowColumn.dtype) ? shadowColumn : null;
118
+ if (shadow !== null) {
119
+ const dtype = shadow.dtype === "f32" ? "f32" : "f64";
120
+ const format = weightFormatter(shadow.dtype);
121
+ return {
122
+ weighted: true,
123
+ dtype,
124
+ isExplicit: (e) => shadow.isSet(e),
125
+ value: (e) => shadow.value(e),
126
+ text: (e, integral = false) => {
127
+ if (!shadow.isSet(e)) {
128
+ return null;
129
+ }
130
+ const value = shadow.value(e);
131
+ return integral && Number.isInteger(value) ? formatInteger(value) : format(value);
132
+ },
133
+ };
134
+ }
135
+ const { weights } = snapshot.edgeList();
136
+ if (weights === null || !snapshot.flags.weighted) {
137
+ return {
138
+ weighted: false,
139
+ dtype: "f32",
140
+ isExplicit: () => false,
141
+ value: () => DEFAULT_WEIGHT,
142
+ text: () => null,
143
+ };
144
+ }
145
+ return {
146
+ weighted: true,
147
+ dtype: "f32",
148
+ isExplicit: () => true,
149
+ value: (e) => weights[e],
150
+ text: (e, integral = false) => {
151
+ const value = weights[e];
152
+ return integral && Number.isInteger(value) ? formatInteger(value) : formatF32(value);
153
+ },
154
+ };
155
+ }
156
+ //# sourceMappingURL=weights.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"weights.js","sourceRoot":"","sources":["../../../src/common/weights.ts"],"names":[],"mappings":"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"}