@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,189 @@
1
+ import { INVALID_INDEX, GraphFormatError } from "@graphty/graph-format";
2
+ const I32_TEXT = /^-?(0|[1-9][0-9]*)$/;
3
+ const F64_TEXT = /^[+-]?((0|[1-9][0-9]*)(\.[0-9]*)?|\.[0-9]+)([eE][+-]?[0-9]+)?$/;
4
+ const I32_MIN = -2147483648;
5
+ const I32_MAX = 2147483647;
6
+ function inferTextDtype(text) {
7
+ if (text === "true" || text === "false") {
8
+ return "bool";
9
+ }
10
+ if (I32_TEXT.test(text)) {
11
+ const n = Number(text);
12
+ if (n >= I32_MIN && n <= I32_MAX) {
13
+ return "i32";
14
+ }
15
+ return Number.isFinite(n) ? "f64" : "string";
16
+ }
17
+ if (F64_TEXT.test(text) && Number.isFinite(Number(text))) {
18
+ return "f64";
19
+ }
20
+ return "string";
21
+ }
22
+ function parseTextCell(text) {
23
+ switch (inferTextDtype(text)) {
24
+ case "bool":
25
+ return text === "true";
26
+ case "i32":
27
+ case "f64":
28
+ return Number(text);
29
+ case "string":
30
+ return text;
31
+ default:
32
+ return text;
33
+ }
34
+ }
35
+ function isNumericText(text) {
36
+ const dtype = inferTextDtype(text);
37
+ return dtype === "i32" || dtype === "f64";
38
+ }
39
+ function isCanonicalNumberText(text, value) {
40
+ return String(value) === text;
41
+ }
42
+ function textDtypeRank(dtype) {
43
+ switch (dtype) {
44
+ case "bool":
45
+ return 0;
46
+ case "i32":
47
+ return 1;
48
+ case "f64":
49
+ return 2;
50
+ case "string":
51
+ return 3;
52
+ default: {
53
+ const name = dtype;
54
+ throw new GraphFormatError("E_UNSUPPORTED", `unknown text dtype ${name}`, { dtype: name });
55
+ }
56
+ }
57
+ }
58
+ class TextCellWriter {
59
+ /**
60
+ * Create a writer; the column is declared by the sink's inference on the first write.
61
+ * @param name - the column name
62
+ * @param domain - node or edge
63
+ * @param sink - the sink
64
+ * @param report - the report the widening warning is recorded in
65
+ */
66
+ constructor(name, domain, sink, report) {
67
+ this.handle = INVALID_INDEX;
68
+ this.textDtype = null;
69
+ this.valueDtype = null;
70
+ this.keptRows = [];
71
+ this.keptTexts = [];
72
+ this.name = name;
73
+ this.domain = domain;
74
+ this.sink = sink;
75
+ this.report = report;
76
+ }
77
+ /**
78
+ * The column handle once the first cell was written.
79
+ * @returns the handle, or INVALID_INDEX before the first write
80
+ */
81
+ get column() {
82
+ return this.handle;
83
+ }
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, text) {
90
+ const kind = inferTextDtype(text);
91
+ const value = parseTextCell(text);
92
+ const wasString = this.textDtype === "string";
93
+ const textDtype = this.textDtype === null || textDtypeRank(kind) > textDtypeRank(this.textDtype) ? kind : this.textDtype;
94
+ this.set(row, textDtype === "string" ? text : value);
95
+ this.textDtype = textDtype;
96
+ const valueKind = kindOfValue(value);
97
+ if (this.valueDtype === null || textDtypeRank(valueKind) > textDtypeRank(this.valueDtype)) {
98
+ this.valueDtype = valueKind;
99
+ }
100
+ if (this.textDtype === "string") {
101
+ if (!wasString && this.keptRows.length > 0) {
102
+ for (let i = 0; i < this.keptRows.length; i++) {
103
+ this.set(this.keptRows[i], this.keptTexts[i]);
104
+ }
105
+ this.keptRows.length = 0;
106
+ this.keptTexts.length = 0;
107
+ }
108
+ return;
109
+ }
110
+ if (typeof value === "number" && !isCanonicalNumberText(text, value)) {
111
+ this.keptRows.push(row);
112
+ this.keptTexts.push(text);
113
+ }
114
+ if (this.textDtype === "f64" && this.valueDtype !== "f64") {
115
+ this.widen("f64");
116
+ }
117
+ }
118
+ /**
119
+ * Write a value (the parsed scalar, or a text into a widened column).
120
+ * @param row - the row
121
+ * @param value - the value
122
+ */
123
+ set(row, value) {
124
+ if (this.handle === INVALID_INDEX) {
125
+ if (this.domain === "node") {
126
+ this.sink.setNodeValue(this.name, row, value);
127
+ this.handle = this.sink.nodeColumn(this.name);
128
+ } else {
129
+ this.sink.setEdgeValue(this.name, row, value);
130
+ this.handle = this.sink.edgeColumn(this.name);
131
+ }
132
+ return;
133
+ }
134
+ if (this.domain === "node") {
135
+ this.sink.setNodeValue(this.handle, row, value);
136
+ } else {
137
+ this.sink.setEdgeValue(this.handle, row, value);
138
+ }
139
+ }
140
+ /**
141
+ * Widen the column to the dtype the text grammar implies, through the sink's optional call.
142
+ * @param dtype - the dtype
143
+ */
144
+ widen(dtype) {
145
+ const { sink } = this;
146
+ const supported = this.domain === "node" ? sink.widenNodeColumn !== void 0 : sink.widenEdgeColumn !== void 0;
147
+ if (!supported) {
148
+ this.report.warnOnce(
149
+ "coercion",
150
+ WIDENING_UNSUPPORTED_CODE,
151
+ `column "${this.name}" holds ${dtype} text but the sink cannot widen an inferred column; it keeps the value-inferred dtype`,
152
+ { element: this.name }
153
+ );
154
+ this.valueDtype = dtype;
155
+ return;
156
+ }
157
+ try {
158
+ if (this.domain === "node") {
159
+ sink.widenNodeColumn?.(this.handle, dtype);
160
+ } else {
161
+ sink.widenEdgeColumn?.(this.handle, dtype);
162
+ }
163
+ this.valueDtype = dtype;
164
+ } catch (err) {
165
+ if (!(err instanceof GraphFormatError) || err.code !== "E_COLUMN_TYPE") {
166
+ throw err;
167
+ }
168
+ this.valueDtype = dtype;
169
+ }
170
+ }
171
+ }
172
+ const WIDENING_UNSUPPORTED_CODE = "W_WIDENING_UNSUPPORTED";
173
+ function kindOfValue(value) {
174
+ if (typeof value === "boolean") {
175
+ return "bool";
176
+ }
177
+ if (typeof value === "string") {
178
+ return "string";
179
+ }
180
+ return Number.isInteger(value) && value >= -2147483648 && value <= 2147483647 && !Object.is(value, -0) ? "i32" : "f64";
181
+ }
182
+ export {
183
+ TextCellWriter as T,
184
+ WIDENING_UNSUPPORTED_CODE as W,
185
+ isNumericText as a,
186
+ inferTextDtype as i,
187
+ parseTextCell as p
188
+ };
189
+ //# sourceMappingURL=text-CajMdVFy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-CajMdVFy.js","sources":["../../src/common/text.ts"],"sourcesContent":["/**\n * The fixed lexical grammar of design section 5.1 for untyped text sources (CSV cells, GML\n * values, DOT strings, Pajek tokens), reproduced from the core's reference implementation so the\n * two agree (invariant I15). Text importers parse each cell with parseTextCell() and push the JS\n * value; the sink's per-column inference then widens `bool -> i32 -> f64 -> string` and never per\n * cell, so a column that saw `1` and then `\"01\"` becomes string for all rows.\n *\n * - `bool` is exactly `true` / `false` (case-sensitive);\n * - `i32` is `/^-?(0|[1-9][0-9]*)$/` within `[-2^31, 2^31)`; `0` / `1` are i32, never bool;\n * - `f64` is a decimal or exponent literal accepted by `Number()` that is not empty, not\n * whitespace, not `Infinity` / `NaN`, not a hex / octal / binary form, has no leading zeros in\n * its integer part, and whose value is finite (an integer literal outside i32 range is f64);\n * - everything else is `string`.\n */\n\nimport { type ColumnHandle, GraphFormatError, type GraphSink, INVALID_INDEX } from \"@graphty/graph-format\";\n\nimport { type ImportReportBuilder } from \"./report.js\";\n\nconst I32_TEXT = /^-?(0|[1-9][0-9]*)$/;\nconst F64_TEXT = /^[+-]?((0|[1-9][0-9]*)(\\.[0-9]*)?|\\.[0-9]+)([eE][+-]?[0-9]+)?$/;\nconst I32_MIN = -2147483648;\nconst I32_MAX = 2147483647;\n\n/**\n * The dtype a text cell parses as under the design section 5.1 grammar.\n * Consumed by the per-format importers and exporters under src/formats.\n * @public\n */\nexport type TextDtype = \"bool\" | \"i32\" | \"f64\" | \"string\";\n\n/**\n * Classify one text cell by the fixed grammar.\n * @param text - the cell text, exactly as read (no trimming)\n * @returns bool, i32, f64 or string\n */\nexport function inferTextDtype(text: string): TextDtype {\n if (text === \"true\" || text === \"false\") {\n return \"bool\";\n }\n if (I32_TEXT.test(text)) {\n const n = Number(text);\n if (n >= I32_MIN && n <= I32_MAX) {\n return \"i32\";\n }\n return Number.isFinite(n) ? \"f64\" : \"string\";\n }\n if (F64_TEXT.test(text) && Number.isFinite(Number(text))) {\n return \"f64\";\n }\n return \"string\";\n}\n\n/**\n * Parse one text cell into the JS value its grammar class implies: a boolean for bool, a number for\n * i32 / f64, the text itself for string. The sink infers the column dtype from the value.\n * @param text - the cell text, exactly as read\n * @returns the value\n */\nexport function parseTextCell(text: string): boolean | number | string {\n switch (inferTextDtype(text)) {\n case \"bool\":\n return text === \"true\";\n case \"i32\":\n case \"f64\":\n return Number(text);\n case \"string\":\n return text;\n default:\n return text;\n }\n}\n\n/**\n * Whether a text cell is a number under the f64 grammar (an i32 or f64 literal).\n * @param text - the cell text\n * @returns true when parseTextCell(text) returns a number\n */\nexport function isNumericText(text: string): boolean {\n const dtype = inferTextDtype(text);\n return dtype === \"i32\" || dtype === \"f64\";\n}\n\n/**\n * Whether a numeric cell text is the canonical spelling of its value (`String(value) === text`),\n * so that the sink's own re-formatting of the value would reproduce it.\n * @param text - the cell text\n * @param value - the parsed value\n * @returns true when the lexical form survives a widening to string\n */\nfunction isCanonicalNumberText(text: string, value: number): boolean {\n return String(value) === text;\n}\n\n/**\n * The widening rank of a text dtype in the design section 5.1 order.\n * @param dtype - the text dtype\n * @returns 0 for bool, 1 for i32, 2 for f64, 3 for string\n */\nfunction textDtypeRank(dtype: TextDtype): number {\n switch (dtype) {\n case \"bool\":\n return 0;\n case \"i32\":\n return 1;\n case \"f64\":\n return 2;\n case \"string\":\n return 3;\n default: {\n const name: string = dtype;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown text dtype ${name}`, { dtype: name });\n }\n }\n}\n\n/**\n * The inferred-column writer of the untyped text formats (CSV, DOT, Pajek; design section 5.1):\n * parses every cell by the fixed grammar and pushes the scalar, and keeps the COLUMN's dtype the\n * one the grammar implies rather than the one the values happen to imply:\n *\n * - a column whose cells are all `2.0`-style f64 text is widened to f64 through the sink's\n * widening call even though every value is integral (the values alone would infer i32);\n * - a numeric cell whose text is not the canonical spelling of its value (`1e5`, `-0`, `1.0`) is\n * remembered, and when a later cell widens the column to string the original texts are written\n * back, so the lexical form is never rewritten by the widening.\n *\n * A sink without the optional widening call keeps the value-inferred dtype and the writer records\n * one W_WIDENING_UNSUPPORTED warning per column.\n * Consumed by the per-format importers under src/formats.\n * @public\n */\nexport class TextCellWriter {\n /** The column name in the sink. */\n readonly name: string;\n\n private readonly domain: \"node\" | \"edge\";\n\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private handle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n /** The widest text dtype seen (the column's dtype under the 5.1 grammar). */\n private textDtype: TextDtype | null = null;\n\n /** The widest dtype the pushed values imply (what the sink inferred on its own). */\n private valueDtype: TextDtype | null = null;\n\n private readonly keptRows: number[] = [];\n\n private readonly keptTexts: string[] = [];\n\n /**\n * Create a writer; the column is declared by the sink's inference on the first write.\n * @param name - the column name\n * @param domain - node or edge\n * @param sink - the sink\n * @param report - the report the widening warning is recorded in\n */\n constructor(name: string, domain: \"node\" | \"edge\", sink: GraphSink, report: ImportReportBuilder) {\n this.name = name;\n this.domain = domain;\n this.sink = sink;\n this.report = report;\n }\n\n /**\n * The column handle once the first cell was written.\n * @returns the handle, or INVALID_INDEX before the first write\n */\n get column(): ColumnHandle {\n return this.handle;\n }\n\n /**\n * Write one cell text.\n * @param row - the node or edge index\n * @param text - the cell text, exactly as read\n */\n write(row: number, text: string): void {\n const kind = inferTextDtype(text);\n const value = parseTextCell(text);\n const wasString = this.textDtype === \"string\";\n const textDtype =\n this.textDtype === null || textDtypeRank(kind) > textDtypeRank(this.textDtype) ? kind : this.textDtype;\n // a string column keeps every cell's lexical form; a numeric text is never re-spelled. The\n // sink may refuse the value (a declared column of another dtype): the state advances only\n // once the cell is written, so a refused cell leaves the writer as it was.\n this.set(row, textDtype === \"string\" ? text : value);\n this.textDtype = textDtype;\n const valueKind = kindOfValue(value);\n if (this.valueDtype === null || textDtypeRank(valueKind) > textDtypeRank(this.valueDtype)) {\n this.valueDtype = valueKind;\n }\n if (this.textDtype === \"string\") {\n if (!wasString && this.keptRows.length > 0) {\n // the sink just widened the column to string from the values; restore the texts\n // whose lexical form the values did not carry\n for (let i = 0; i < this.keptRows.length; i++) {\n this.set(this.keptRows[i], this.keptTexts[i]);\n }\n this.keptRows.length = 0;\n this.keptTexts.length = 0;\n }\n return;\n }\n if (typeof value === \"number\" && !isCanonicalNumberText(text, value)) {\n this.keptRows.push(row);\n this.keptTexts.push(text);\n }\n if (this.textDtype === \"f64\" && this.valueDtype !== \"f64\") {\n this.widen(\"f64\");\n }\n }\n\n /**\n * Write a value (the parsed scalar, or a text into a widened column).\n * @param row - the row\n * @param value - the value\n */\n private set(row: number, value: unknown): void {\n if (this.handle === INVALID_INDEX) {\n if (this.domain === \"node\") {\n this.sink.setNodeValue(this.name, row, value);\n this.handle = this.sink.nodeColumn(this.name);\n } else {\n this.sink.setEdgeValue(this.name, row, value);\n this.handle = this.sink.edgeColumn(this.name);\n }\n return;\n }\n if (this.domain === \"node\") {\n this.sink.setNodeValue(this.handle, row, value);\n } else {\n this.sink.setEdgeValue(this.handle, row, value);\n }\n }\n\n /**\n * Widen the column to the dtype the text grammar implies, through the sink's optional call.\n * @param dtype - the dtype\n */\n private widen(dtype: \"f64\"): void {\n const { sink } = this;\n const supported =\n this.domain === \"node\" ? sink.widenNodeColumn !== undefined : sink.widenEdgeColumn !== undefined;\n if (!supported) {\n this.report.warnOnce(\n \"coercion\",\n WIDENING_UNSUPPORTED_CODE,\n `column \"${this.name}\" holds ${dtype} text but the sink cannot widen an inferred column; it keeps the value-inferred dtype`,\n { element: this.name },\n );\n this.valueDtype = dtype;\n return;\n }\n try {\n if (this.domain === \"node\") {\n sink.widenNodeColumn?.(this.handle, dtype);\n } else {\n sink.widenEdgeColumn?.(this.handle, dtype);\n }\n this.valueDtype = dtype;\n } catch (err) {\n if (!(err instanceof GraphFormatError) || err.code !== \"E_COLUMN_TYPE\") {\n throw err;\n }\n // a caller's declared column of the name: its dtype stands\n this.valueDtype = dtype;\n }\n }\n}\n\n/** Issue code: the sink has no widening call, so a text column keeps the dtype its values imply. */\nexport const WIDENING_UNSUPPORTED_CODE = \"W_WIDENING_UNSUPPORTED\";\n\n/**\n * The text dtype a parsed cell value implies on its own (what the sink's inference sees).\n * @param value - the parsed value\n * @returns the dtype\n */\nfunction kindOfValue(value: boolean | number | string): TextDtype {\n if (typeof value === \"boolean\") {\n return \"bool\";\n }\n if (typeof value === \"string\") {\n return \"string\";\n }\n return Number.isInteger(value) && value >= -2147483648 && value <= 2147483647 && !Object.is(value, -0)\n ? \"i32\"\n : \"f64\";\n}\n"],"names":[],"mappings":"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"}