@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,274 @@
1
+ /**
2
+ * The ImportReport builder shared by every importer (design section 8.6): issues by category and
3
+ * severity, the element counts, loss notes, the error limit with truncation, and the ImportError
4
+ * that carries the partial report when the importer aborts.
5
+ *
6
+ * Layering (design section 8.6): the builder throws on the first hard error; the importer catches
7
+ * per element, records an ImportIssue through this class, skips the element and continues until the
8
+ * error limit, then aborts with E_IMPORT. `recordError()` is that catch: it turns a thrown
9
+ * GraphFormatError into an issue with the category its code implies and re-throws everything else
10
+ * (an ImportError, an abort reason, a programming error) unchanged.
11
+ */
12
+ import { GraphFormatError } from "@graphty/graph-format";
13
+ import { ImportError } from "../types.js";
14
+ /**
15
+ * The category a thrown GraphFormatError maps to when an importer catches it per element: the codes
16
+ * that mean "the file referenced something it never declared" are missing values, a refused
17
+ * direction change is a coercion, size and feature limits are unsupported, everything else is a
18
+ * validation error of the element.
19
+ */
20
+ const CATEGORY_BY_CODE = {
21
+ E_UNKNOWN_NODE: "missing-value",
22
+ E_UNKNOWN_COLUMN: "missing-value",
23
+ E_DIRECTED: "coercion",
24
+ E_TOO_LARGE: "unsupported",
25
+ E_UNSUPPORTED: "unsupported",
26
+ E_GPU_INELIGIBLE: "unsupported",
27
+ };
28
+ /**
29
+ * The code a report used to give a thrown value that was not a GraphFormatError. Since audit round
30
+ * 1 such a value (a TypeError, a RangeError: a bug in an importer or a sink, never a defect of the
31
+ * input) propagates out of import() untouched, so no importer records this code any more; the
32
+ * constant stays for consumers that switch on the codes of earlier reports.
33
+ */
34
+ export const PARSE_ERROR_CODE = "E_PARSE";
35
+ /**
36
+ * Accumulates an ImportReport while an importer runs. Errors count toward the error limit; the
37
+ * error that takes the count beyond the limit is still recorded, `truncated` is set, and an
38
+ * ImportError carrying the report so far is thrown (design section 8.4: "beyond it the importer
39
+ * aborts with E_IMPORT"). Warnings never abort.
40
+ */
41
+ export class ImportReportBuilder {
42
+ /**
43
+ * Create a builder for one import call.
44
+ * @param format - the importer's format name
45
+ * @param errorLimit - errors tolerated before the import aborts; Infinity for no limit
46
+ */
47
+ constructor(format, errorLimit) {
48
+ /** The element counters; importers increment them directly. */
49
+ this.counts = { nodes: 0, edges: 0, skippedNodes: 0, skippedEdges: 0, expandedMixed: 0 };
50
+ this.issueList = [];
51
+ this.lossList = [];
52
+ this.onceCodes = new Set();
53
+ this.errors = 0;
54
+ this.warnings = 0;
55
+ this.truncatedFlag = false;
56
+ this.format = format;
57
+ this.errorLimit = errorLimit;
58
+ this.startedAt = now();
59
+ }
60
+ /**
61
+ * Issues recorded so far, in order.
62
+ * @returns the live list (not copied; finish() copies)
63
+ */
64
+ get issues() {
65
+ return this.issueList;
66
+ }
67
+ /**
68
+ * Issues with severity "error".
69
+ * @returns the count
70
+ */
71
+ get errorCount() {
72
+ return this.errors;
73
+ }
74
+ /**
75
+ * Issues with severity "warning".
76
+ * @returns the count
77
+ */
78
+ get warningCount() {
79
+ return this.warnings;
80
+ }
81
+ /**
82
+ * Whether the error limit was exceeded.
83
+ * @returns true once an error beyond the limit was recorded
84
+ */
85
+ get truncated() {
86
+ return this.truncatedFlag;
87
+ }
88
+ /**
89
+ * Loss notes recorded so far.
90
+ * @returns the live list
91
+ */
92
+ get lossy() {
93
+ return this.lossList;
94
+ }
95
+ /**
96
+ * Record an error. When the count goes beyond the error limit the report is marked truncated
97
+ * and an ImportError carrying it is thrown; the importer does not catch that.
98
+ * @param category - the issue category
99
+ * @param code - a stable code such as "E_UNKNOWN_NODE"
100
+ * @param message - a plain-ASCII message
101
+ * @param where - the line and element, when known
102
+ * @returns the recorded issue
103
+ */
104
+ error(category, code, message, where) {
105
+ const issue = makeIssue(category, "error", code, message, where);
106
+ this.issueList.push(issue);
107
+ this.errors++;
108
+ if (this.errors > this.errorLimit) {
109
+ this.truncatedFlag = true;
110
+ throw this.abort(`error limit of ${this.errorLimit} exceeded: ${message}`, {
111
+ code,
112
+ limit: this.errorLimit,
113
+ });
114
+ }
115
+ return issue;
116
+ }
117
+ /**
118
+ * Record a warning; warnings never count toward the limit.
119
+ * @param category - the issue category
120
+ * @param code - a stable code such as "W_WIDENED"
121
+ * @param message - a plain-ASCII message
122
+ * @param where - the line and element, when known
123
+ * @returns the recorded issue
124
+ */
125
+ warning(category, code, message, where) {
126
+ const issue = makeIssue(category, "warning", code, message, where);
127
+ this.issueList.push(issue);
128
+ this.warnings++;
129
+ return issue;
130
+ }
131
+ /**
132
+ * Record a warning the first time its key is seen and ignore later repeats, for conditions
133
+ * that would otherwise produce one warning per row.
134
+ * @param category - the issue category
135
+ * @param code - the stable code
136
+ * @param message - a plain-ASCII message
137
+ * @param where - the line and element, when known
138
+ * @param key - what repeats are deduplicated on; the code itself by default (pass `code:column`
139
+ * to warn once per column)
140
+ * @returns the recorded issue, or null when the key was already recorded
141
+ */
142
+ warnOnce(category, code, message, where, key = code) {
143
+ if (this.onceCodes.has(key)) {
144
+ return null;
145
+ }
146
+ this.onceCodes.add(key);
147
+ return this.warning(category, code, message, where);
148
+ }
149
+ /**
150
+ * Record something the importer could not represent.
151
+ * @param code - a stable code
152
+ * @param message - a plain-ASCII message
153
+ * @param column - the affected column, or null
154
+ * @param count - the affected count, or null
155
+ * @returns the recorded note
156
+ */
157
+ loss(code, message, column = null, count = null) {
158
+ const note = Object.freeze({ code, message, column, count });
159
+ this.lossList.push(note);
160
+ return note;
161
+ }
162
+ /**
163
+ * The per-element catch of design section 8.6: record a thrown GraphFormatError as an error
164
+ * issue with its code and the category the code implies. Anything else is re-thrown unchanged:
165
+ * an ImportError (the import already aborted), an abort reason, and any other thrown value (a
166
+ * TypeError or RangeError is a programming error in the importer or the sink, never a defect of
167
+ * the input, so it must surface as an exception rather than as an issue blamed on the file).
168
+ * @param err - the thrown value
169
+ * @param where - the line and element, when known
170
+ * @returns the recorded issue
171
+ */
172
+ recordError(err, where) {
173
+ if (err instanceof GraphFormatError && !(err instanceof ImportError)) {
174
+ const category = CATEGORY_BY_CODE[err.code] ?? "validation-error";
175
+ return this.error(category, err.code, err.message, where);
176
+ }
177
+ throw err;
178
+ }
179
+ /**
180
+ * Build the ImportError that aborts the import, carrying the report so far. The caller throws
181
+ * it; this method only constructs it so it can be used in expression position.
182
+ * @param message - a plain-ASCII message
183
+ * @param details - optional machine-readable context
184
+ * @returns the error to throw
185
+ */
186
+ abort(message, details) {
187
+ return new ImportError(message, this.finish(), details);
188
+ }
189
+ /**
190
+ * Record a fatal parse error and abort: the issue is recorded (even beyond the error limit)
191
+ * and an ImportError carrying the report is thrown.
192
+ * @param code - a stable code such as "E_INVALID_UTF8"
193
+ * @param message - a plain-ASCII message
194
+ * @param where - the line and element, when known
195
+ * @param details - optional machine-readable context for the ImportError
196
+ */
197
+ fail(code, message, where, details) {
198
+ const issue = makeIssue("parse-error", "error", code, message, where);
199
+ this.issueList.push(issue);
200
+ this.errors++;
201
+ if (this.errors > this.errorLimit) {
202
+ this.truncatedFlag = true;
203
+ }
204
+ throw this.abort(message, { code, ...details });
205
+ }
206
+ /**
207
+ * The report as it stands: a frozen snapshot with the parse duration so far. Can be called more
208
+ * than once; each call reflects everything recorded up to that point.
209
+ * @returns the report
210
+ */
211
+ finish() {
212
+ const { nodes, edges, skippedNodes, skippedEdges, expandedMixed } = this.counts;
213
+ return Object.freeze({
214
+ format: this.format,
215
+ counts: Object.freeze({ nodes, edges, skippedNodes, skippedEdges, expandedMixed }),
216
+ issues: Object.freeze([...this.issueList]),
217
+ errorCount: this.errors,
218
+ warningCount: this.warnings,
219
+ truncated: this.truncatedFlag,
220
+ lossy: Object.freeze([...this.lossList]),
221
+ durationMs: now() - this.startedAt,
222
+ });
223
+ }
224
+ }
225
+ /**
226
+ * Build a frozen ImportIssue.
227
+ * @param category - the category
228
+ * @param severity - error or warning
229
+ * @param code - the stable code
230
+ * @param message - the message
231
+ * @param where - the location, when known
232
+ * @returns the issue
233
+ */
234
+ function makeIssue(category, severity, code, message, where) {
235
+ return Object.freeze({
236
+ category,
237
+ severity,
238
+ code,
239
+ message,
240
+ line: where?.line ?? null,
241
+ element: where?.element ?? null,
242
+ });
243
+ }
244
+ /**
245
+ * Whether a thrown value is an abort reason (the DOMException or Error named "AbortError" that
246
+ * AbortSignal.reason holds), which an importer must let through untouched.
247
+ * @param err - the thrown value
248
+ * @returns true for an AbortError
249
+ */
250
+ export function isAbortError(err) {
251
+ return typeof err === "object" && err !== null && err.name === "AbortError";
252
+ }
253
+ /**
254
+ * The message of a thrown value: an Error's message, a string as is, anything else described by type.
255
+ * @param err - the thrown value
256
+ * @returns a plain message
257
+ */
258
+ export function messageOf(err) {
259
+ if (err instanceof Error) {
260
+ return err.message;
261
+ }
262
+ if (typeof err === "string") {
263
+ return err;
264
+ }
265
+ return `non-error thrown (${typeof err})`;
266
+ }
267
+ /**
268
+ * A monotonic millisecond clock: performance.now() where it exists, Date.now() otherwise.
269
+ * @returns milliseconds
270
+ */
271
+ function now() {
272
+ return typeof performance === "object" ? performance.now() : Date.now();
273
+ }
274
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/common/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Temporal values (design section 5.1): `date` / `dateTime` attributes, GEXF time bounds and Neo4j
3
+ * temporal types become f64 epoch milliseconds (or the raw numeric time when the file's timeformat
4
+ * is integer / double). When a value's canonical re-formatting would differ from the source text (a
5
+ * UTC offset, fractional seconds beyond milliseconds, a date without a time in a dateTime column)
6
+ * the importer also keeps the lexical form in a companion `<column>.text` column with role
7
+ * `timeText`; the exporter emits the text when present and formats the number otherwise.
8
+ *
9
+ * Only ISO-8601 forms are parsed (XSD date / dateTime / time and Neo4j's literals), by a fixed
10
+ * grammar rather than Date.parse, so two hosts agree on every value.
11
+ */
12
+ import { type ColumnDecl, type ColumnRole } from "@graphty/graph-format";
13
+ /** The temporal kinds a declared type can map to; each fixes the parse grammar and the canonical text. */
14
+ export type TemporalKind = "date" | "dateTime" | "localDateTime" | "time" | "localTime";
15
+ /**
16
+ * The GEXF `timeformat` values (design section 5.9).
17
+ * Consumed by the per-format importers and exporters under src/formats.
18
+ * @public
19
+ */
20
+ export type TimeFormat = "integer" | "double" | "date" | "dateTime";
21
+ /** A parsed temporal value: the number stored in the column and the source text when it must be kept. */
22
+ export interface TemporalValue {
23
+ /** Epoch milliseconds (date, dateTime, localDateTime), milliseconds since midnight (time, localTime), or the raw number. */
24
+ readonly value: number;
25
+ /** The source text when formatTemporal(value) would not reproduce it; null otherwise. */
26
+ readonly text: string | null;
27
+ }
28
+ /** The role of a companion text column. */
29
+ export declare const TIME_TEXT_ROLE: ColumnRole;
30
+ /** The suffix of a companion text column's name. */
31
+ export declare const TIME_TEXT_SUFFIX = ".text";
32
+ /**
33
+ * Parse an ISO-8601 temporal text of one kind.
34
+ * @param text - the source text (already trimmed)
35
+ * @param kind - the temporal kind
36
+ * @returns the value and, when the canonical form differs, the source text; E_COLUMN_TYPE when the text is not of the kind
37
+ */
38
+ export declare function parseTemporal(text: string, kind: TemporalKind): TemporalValue;
39
+ /**
40
+ * Parse a GEXF time bound (`start`, `end`, `timestamp`, a spell or an attvalue time) under the
41
+ * graph's timeformat: integer / double values are numbers as written; date / dateTime values are
42
+ * ISO text; when the format is unknown (absent header) numeric text is a number and anything else
43
+ * is tried as dateTime.
44
+ * @param text - the source text
45
+ * @param timeFormat - the graph's timeformat, or null when the file declares none
46
+ * @returns the value and the source text when it must be kept
47
+ */
48
+ export declare function parseTimeText(text: string, timeFormat: TimeFormat | null): TemporalValue;
49
+ /**
50
+ * Format a temporal value in its canonical ISO-8601 form.
51
+ * @param value - the number as stored
52
+ * @param kind - the temporal kind
53
+ * @returns the canonical text: `YYYY-MM-DD`, `YYYY-MM-DDTHH:MM:SS[.mmm]Z`, `YYYY-MM-DDTHH:MM:SS[.mmm]`,
54
+ * `HH:MM:SS[.mmm]Z` or `HH:MM:SS[.mmm]`
55
+ */
56
+ export declare function formatTemporal(value: number, kind: TemporalKind): string;
57
+ /**
58
+ * Format a GEXF time bound under the graph's timeformat: the number's shortest text for integer /
59
+ * double, the canonical ISO form otherwise.
60
+ * @param value - the value as stored
61
+ * @param timeFormat - the graph's timeformat, or null for a file that declares none (double)
62
+ * @returns the text
63
+ */
64
+ export declare function formatTimeValue(value: number, timeFormat: TimeFormat | null): string;
65
+ /**
66
+ * The declaration of the companion text column of a temporal column (design section 5.1).
67
+ * @param column - the temporal column's name
68
+ * @returns a string column named `<column>.text` with role timeText and `extra.for` naming the column
69
+ */
70
+ export declare function timeTextCompanion(column: string): ColumnDecl;
71
+ //# sourceMappingURL=temporal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal.d.ts","sourceRoot":"","sources":["../../../src/common/temporal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAoB,MAAM,uBAAuB,CAAC;AAE3F,0GAA0G;AAC1G,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,eAAe,GAAG,MAAM,GAAG,WAAW,CAAC;AAExF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AAEpE,yGAAyG;AACzG,MAAM,WAAW,aAAa;IAC1B,4HAA4H;IAC5H,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,2CAA2C;AAC3C,eAAO,MAAM,cAAc,EAAE,UAAuB,CAAC;AAErD,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,UAAU,CAAC;AAUxC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,aAAa,CAmB7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,aAAa,CAiBxF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,MAAM,CA2BxE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,GAAG,MAAM,CAepF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAQ5D"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Temporal values (design section 5.1): `date` / `dateTime` attributes, GEXF time bounds and Neo4j
3
+ * temporal types become f64 epoch milliseconds (or the raw numeric time when the file's timeformat
4
+ * is integer / double). When a value's canonical re-formatting would differ from the source text (a
5
+ * UTC offset, fractional seconds beyond milliseconds, a date without a time in a dateTime column)
6
+ * the importer also keeps the lexical form in a companion `<column>.text` column with role
7
+ * `timeText`; the exporter emits the text when present and formats the number otherwise.
8
+ *
9
+ * Only ISO-8601 forms are parsed (XSD date / dateTime / time and Neo4j's literals), by a fixed
10
+ * grammar rather than Date.parse, so two hosts agree on every value.
11
+ */
12
+ import { GraphFormatError } from "@graphty/graph-format";
13
+ /** The role of a companion text column. */
14
+ export const TIME_TEXT_ROLE = "timeText";
15
+ /** The suffix of a companion text column's name. */
16
+ export const TIME_TEXT_SUFFIX = ".text";
17
+ const DATE_TIME = /^(-?[0-9]{4,})-([0-9]{2})-([0-9]{2})(?:[T ]([0-9]{2}):([0-9]{2})(?::([0-9]{2})(?:\.([0-9]{1,9}))?)?)?(Z|z|[+-][0-9]{2}(?::?[0-9]{2})?)?$/;
18
+ const TIME = /^([0-9]{2}):([0-9]{2})(?::([0-9]{2})(?:\.([0-9]{1,9}))?)?(Z|z|[+-][0-9]{2}(?::?[0-9]{2})?)?$/;
19
+ const NUMERIC = /^[+-]?([0-9]+(\.[0-9]*)?|\.[0-9]+)([eE][+-]?[0-9]+)?$/;
20
+ const MS_PER_MINUTE = 60000;
21
+ const MS_PER_DAY = 86400000;
22
+ /**
23
+ * Parse an ISO-8601 temporal text of one kind.
24
+ * @param text - the source text (already trimmed)
25
+ * @param kind - the temporal kind
26
+ * @returns the value and, when the canonical form differs, the source text; E_COLUMN_TYPE when the text is not of the kind
27
+ */
28
+ export function parseTemporal(text, kind) {
29
+ let value;
30
+ switch (kind) {
31
+ case "date":
32
+ case "dateTime":
33
+ case "localDateTime":
34
+ value = parseDateTime(text, kind);
35
+ break;
36
+ case "time":
37
+ case "localTime":
38
+ value = parseTime(text, kind);
39
+ break;
40
+ default: {
41
+ const name = kind;
42
+ throw new GraphFormatError("E_COLUMN_TYPE", `unknown temporal kind ${name}`, { kind: name });
43
+ }
44
+ }
45
+ const canonical = formatTemporal(value, kind);
46
+ return { value, text: canonical === text ? null : text };
47
+ }
48
+ /**
49
+ * Parse a GEXF time bound (`start`, `end`, `timestamp`, a spell or an attvalue time) under the
50
+ * graph's timeformat: integer / double values are numbers as written; date / dateTime values are
51
+ * ISO text; when the format is unknown (absent header) numeric text is a number and anything else
52
+ * is tried as dateTime.
53
+ * @param text - the source text
54
+ * @param timeFormat - the graph's timeformat, or null when the file declares none
55
+ * @returns the value and the source text when it must be kept
56
+ */
57
+ export function parseTimeText(text, timeFormat) {
58
+ const trimmed = text.trim();
59
+ switch (timeFormat) {
60
+ case "integer":
61
+ case "double":
62
+ return parseNumericTime(trimmed);
63
+ case "date":
64
+ return parseTemporal(trimmed, "date");
65
+ case "dateTime":
66
+ return parseTemporal(trimmed, "dateTime");
67
+ case null:
68
+ return NUMERIC.test(trimmed) ? parseNumericTime(trimmed) : parseTemporal(trimmed, "dateTime");
69
+ default: {
70
+ const name = timeFormat;
71
+ throw new GraphFormatError("E_COLUMN_TYPE", `unknown timeformat ${name}`, { timeFormat: name });
72
+ }
73
+ }
74
+ }
75
+ /**
76
+ * Format a temporal value in its canonical ISO-8601 form.
77
+ * @param value - the number as stored
78
+ * @param kind - the temporal kind
79
+ * @returns the canonical text: `YYYY-MM-DD`, `YYYY-MM-DDTHH:MM:SS[.mmm]Z`, `YYYY-MM-DDTHH:MM:SS[.mmm]`,
80
+ * `HH:MM:SS[.mmm]Z` or `HH:MM:SS[.mmm]`
81
+ */
82
+ export function formatTemporal(value, kind) {
83
+ switch (kind) {
84
+ case "date": {
85
+ const d = new Date(value);
86
+ return `${year(d)}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())}`;
87
+ }
88
+ case "dateTime":
89
+ case "localDateTime": {
90
+ const d = new Date(value);
91
+ const date = `${year(d)}-${pad2(d.getUTCMonth() + 1)}-${pad2(d.getUTCDate())}`;
92
+ const time = clock(d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());
93
+ return kind === "dateTime" ? `${date}T${time}Z` : `${date}T${time}`;
94
+ }
95
+ case "time":
96
+ case "localTime": {
97
+ const ms = ((value % MS_PER_DAY) + MS_PER_DAY) % MS_PER_DAY;
98
+ const h = Math.floor(ms / 3600000);
99
+ const m = Math.floor((ms % 3600000) / MS_PER_MINUTE);
100
+ const s = Math.floor((ms % MS_PER_MINUTE) / 1000);
101
+ const text = clock(h, m, s, ms % 1000);
102
+ return kind === "time" ? `${text}Z` : text;
103
+ }
104
+ default: {
105
+ const name = kind;
106
+ throw new GraphFormatError("E_COLUMN_TYPE", `unknown temporal kind ${name}`, { kind: name });
107
+ }
108
+ }
109
+ }
110
+ /**
111
+ * Format a GEXF time bound under the graph's timeformat: the number's shortest text for integer /
112
+ * double, the canonical ISO form otherwise.
113
+ * @param value - the value as stored
114
+ * @param timeFormat - the graph's timeformat, or null for a file that declares none (double)
115
+ * @returns the text
116
+ */
117
+ export function formatTimeValue(value, timeFormat) {
118
+ switch (timeFormat) {
119
+ case "date":
120
+ return formatTemporal(value, "date");
121
+ case "dateTime":
122
+ return formatTemporal(value, "dateTime");
123
+ case "integer":
124
+ case "double":
125
+ case null:
126
+ return String(value);
127
+ default: {
128
+ const name = timeFormat;
129
+ throw new GraphFormatError("E_COLUMN_TYPE", `unknown timeformat ${name}`, { timeFormat: name });
130
+ }
131
+ }
132
+ }
133
+ /**
134
+ * The declaration of the companion text column of a temporal column (design section 5.1).
135
+ * @param column - the temporal column's name
136
+ * @returns a string column named `<column>.text` with role timeText and `extra.for` naming the column
137
+ */
138
+ export function timeTextCompanion(column) {
139
+ return {
140
+ name: column + TIME_TEXT_SUFFIX,
141
+ dtype: "string",
142
+ role: TIME_TEXT_ROLE,
143
+ nullable: true,
144
+ extra: { for: column },
145
+ };
146
+ }
147
+ /**
148
+ * Parse a numeric time bound.
149
+ * @param text - the trimmed source text
150
+ * @returns the number; the text is kept when String(value) differs from it
151
+ */
152
+ function parseNumericTime(text) {
153
+ if (!NUMERIC.test(text)) {
154
+ throw new GraphFormatError("E_COLUMN_TYPE", `"${text}" is not a numeric time`, { value: text });
155
+ }
156
+ const value = Number(text);
157
+ return { value, text: String(value) === text ? null : text };
158
+ }
159
+ /**
160
+ * Parse a date or date-time text into epoch milliseconds.
161
+ * @param text - the source text
162
+ * @param kind - date (a time part is accepted and kept in the companion), dateTime or localDateTime
163
+ * @returns epoch milliseconds
164
+ */
165
+ function parseDateTime(text, kind) {
166
+ const m = DATE_TIME.exec(text);
167
+ if (m === null) {
168
+ throw new GraphFormatError("E_COLUMN_TYPE", `"${text}" is not an ISO-8601 ${kind}`, { value: text, kind });
169
+ }
170
+ const y = Number(m[1]);
171
+ const month = Number(m[2]);
172
+ const day = Number(m[3]);
173
+ const hour = m[4] === undefined ? 0 : Number(m[4]);
174
+ const minute = m[5] === undefined ? 0 : Number(m[5]);
175
+ const second = m[6] === undefined ? 0 : Number(m[6]);
176
+ const ms = m[7] === undefined ? 0 : fractionMs(m[7]);
177
+ if (month < 1 || month > 12 || day < 1 || day > 31 || hour > 24 || minute > 59 || second > 60) {
178
+ throw new GraphFormatError("E_COLUMN_TYPE", `"${text}" is out of range for a ${kind}`, { value: text, kind });
179
+ }
180
+ // Date.UTC maps years 0..99 to 1900..1999; the setters do not
181
+ const d = new Date(0);
182
+ d.setUTCFullYear(y, month - 1, day);
183
+ d.setUTCHours(hour, minute, second, ms);
184
+ if (d.getUTCDate() !== day && hour !== 24) {
185
+ throw new GraphFormatError("E_COLUMN_TYPE", `"${text}" is not a calendar date`, { value: text, kind });
186
+ }
187
+ const offset = m[8] === undefined ? 0 : offsetMinutes(m[8]);
188
+ return d.getTime() - offset * MS_PER_MINUTE;
189
+ }
190
+ /**
191
+ * Parse a time-of-day text into milliseconds since midnight (UTC for `time` with a zone).
192
+ * @param text - the source text
193
+ * @param kind - time or localTime
194
+ * @returns milliseconds since midnight in 0..86400000
195
+ */
196
+ function parseTime(text, kind) {
197
+ const m = TIME.exec(text);
198
+ if (m === null) {
199
+ throw new GraphFormatError("E_COLUMN_TYPE", `"${text}" is not an ISO-8601 ${kind}`, { value: text, kind });
200
+ }
201
+ const hour = Number(m[1]);
202
+ const minute = Number(m[2]);
203
+ const second = m[3] === undefined ? 0 : Number(m[3]);
204
+ const ms = m[4] === undefined ? 0 : fractionMs(m[4]);
205
+ if (hour > 24 || minute > 59 || second > 60) {
206
+ throw new GraphFormatError("E_COLUMN_TYPE", `"${text}" is out of range for a ${kind}`, { value: text, kind });
207
+ }
208
+ const local = ((hour * 60 + minute) * 60 + second) * 1000 + ms;
209
+ const offset = m[5] === undefined ? 0 : offsetMinutes(m[5]);
210
+ const utc = local - offset * MS_PER_MINUTE;
211
+ return ((utc % MS_PER_DAY) + MS_PER_DAY) % MS_PER_DAY;
212
+ }
213
+ /**
214
+ * Milliseconds of a fractional-second text (1 to 9 digits), truncated to whole milliseconds.
215
+ * @param digits - the digits after the decimal point
216
+ * @returns 0..999
217
+ */
218
+ function fractionMs(digits) {
219
+ return Math.floor(Number(`0.${digits}`) * 1000);
220
+ }
221
+ /**
222
+ * The minutes of a zone designator.
223
+ * @param zone - "Z", "+HH:MM", "+HHMM" or "+HH"
224
+ * @returns signed minutes east of UTC
225
+ */
226
+ function offsetMinutes(zone) {
227
+ if (zone === "Z" || zone === "z") {
228
+ return 0;
229
+ }
230
+ const sign = zone.startsWith("-") ? -1 : 1;
231
+ const digits = zone.slice(1).replace(":", "");
232
+ const hours = Number(digits.slice(0, 2));
233
+ const minutes = digits.length > 2 ? Number(digits.slice(2, 4)) : 0;
234
+ return sign * (hours * 60 + minutes);
235
+ }
236
+ /**
237
+ * Two-digit zero-padded text.
238
+ * @param n - 0..99
239
+ * @returns the text
240
+ */
241
+ function pad2(n) {
242
+ return n < 10 ? `0${n}` : String(n);
243
+ }
244
+ /**
245
+ * The year of a UTC date as at least four digits (negative years keep their sign).
246
+ * @param d - the date
247
+ * @returns the text
248
+ */
249
+ function year(d) {
250
+ const y = d.getUTCFullYear();
251
+ const abs = String(Math.abs(y)).padStart(4, "0");
252
+ return y < 0 ? `-${abs}` : abs;
253
+ }
254
+ /**
255
+ * `HH:MM:SS` with `.mmm` appended when the milliseconds are not zero.
256
+ * @param h - hours
257
+ * @param m - minutes
258
+ * @param s - seconds
259
+ * @param ms - milliseconds
260
+ * @returns the text
261
+ */
262
+ function clock(h, m, s, ms) {
263
+ const base = `${pad2(h)}:${pad2(m)}:${pad2(s)}`;
264
+ return ms === 0 ? base : `${base}.${String(ms).padStart(3, "0")}`;
265
+ }
266
+ //# sourceMappingURL=temporal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal.js","sourceRoot":"","sources":["../../../src/common/temporal.ts"],"names":[],"mappings":"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"}