@graphty/graph-io 0.3.40 → 0.3.42

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 (210) hide show
  1. package/README.md +2 -0
  2. package/dist/chunks/{children-CL3Cy0ez.js → children-CA4coBi0.js} +36 -27
  3. package/dist/chunks/children-CA4coBi0.js.map +1 -0
  4. package/dist/chunks/{choose-CS3fvGT1.js → choose-DvpbdRuz.js} +2 -2
  5. package/dist/chunks/{choose-CS3fvGT1.js.map → choose-DvpbdRuz.js.map} +1 -1
  6. package/dist/chunks/{constants-DqKZT6cH.js → constants-fT3E8JYY.js} +2 -2
  7. package/dist/chunks/{constants-DqKZT6cH.js.map → constants-fT3E8JYY.js.map} +1 -1
  8. package/dist/chunks/{escape-BJRLd3vJ.js → escape-B62ZGM_a.js} +2 -2
  9. package/dist/chunks/{escape-BJRLd3vJ.js.map → escape-B62ZGM_a.js.map} +1 -1
  10. package/dist/chunks/{export-B-aVCwyG.js → export-rKLeGQMo.js} +404 -243
  11. package/dist/chunks/export-rKLeGQMo.js.map +1 -0
  12. package/dist/chunks/{exporter-6ocL_9x_.js → exporter-8hLNemFk.js} +4 -4
  13. package/dist/chunks/{exporter-6ocL_9x_.js.map → exporter-8hLNemFk.js.map} +1 -1
  14. package/dist/chunks/{exporter-BVXnV9-9.js → exporter-BWwEuOPT.js} +29 -17
  15. package/dist/chunks/exporter-BWwEuOPT.js.map +1 -0
  16. package/dist/chunks/{exporter-Bcp-l4Bo.js → exporter-CpRyHZ3H.js} +574 -475
  17. package/dist/chunks/exporter-CpRyHZ3H.js.map +1 -0
  18. package/dist/chunks/{exporter-SFYkDzD0.js → exporter-yLxKBvLE.js} +23 -20
  19. package/dist/chunks/{exporter-SFYkDzD0.js.map → exporter-yLxKBvLE.js.map} +1 -1
  20. package/dist/chunks/{importer-DcKB97kW.js → importer-BbNb7eNg.js} +111 -71
  21. package/dist/chunks/importer-BbNb7eNg.js.map +1 -0
  22. package/dist/chunks/{importer-D_srHyj6.js → importer-C98dpSH4.js} +5 -5
  23. package/dist/chunks/{importer-D_srHyj6.js.map → importer-C98dpSH4.js.map} +1 -1
  24. package/dist/chunks/{importer-BJlGAOht.js → importer-D794XUTe.js} +3 -3
  25. package/dist/chunks/{importer-BJlGAOht.js.map → importer-D794XUTe.js.map} +1 -1
  26. package/dist/chunks/{importer-AjwOJrn2.js → importer-Dz7tI8Sa.js} +202 -181
  27. package/dist/chunks/importer-Dz7tI8Sa.js.map +1 -0
  28. package/dist/chunks/{importer-DEp_fYjf.js → importer-Ht7LNg8L.js} +92 -64
  29. package/dist/chunks/importer-Ht7LNg8L.js.map +1 -0
  30. package/dist/chunks/{importer-CPqnIY8m.js → importer-WrGRZb0N.js} +42 -29
  31. package/dist/chunks/importer-WrGRZb0N.js.map +1 -0
  32. package/dist/chunks/{importer-BpuS3J8C.js → importer-xZ-3suY1.js} +74 -61
  33. package/dist/chunks/importer-xZ-3suY1.js.map +1 -0
  34. package/dist/chunks/{json-elements-DpO6AXIc.js → json-elements-DKSqpNW1.js} +3 -3
  35. package/dist/chunks/{json-elements-DpO6AXIc.js.map → json-elements-DKSqpNW1.js.map} +1 -1
  36. package/dist/chunks/{ontology-export-50L9DOV4.js → ontology-export-CtRXjg_i.js} +2 -2
  37. package/dist/chunks/{ontology-export-50L9DOV4.js.map → ontology-export-CtRXjg_i.js.map} +1 -1
  38. package/dist/chunks/{records-r3SFHz11.js → records-Cu4bxYOm.js} +69 -36
  39. package/dist/chunks/records-Cu4bxYOm.js.map +1 -0
  40. package/dist/chunks/{text-Bjfa1xYL.js → text-DHOJXnED.js} +20 -11
  41. package/dist/chunks/text-DHOJXnED.js.map +1 -0
  42. package/dist/csv.js +323 -241
  43. package/dist/csv.js.map +1 -1
  44. package/dist/cx.js +1 -1
  45. package/dist/cx2.js +2 -2
  46. package/dist/cys.js +1 -1
  47. package/dist/dot.js +1 -1
  48. package/dist/gexf.js +195 -97
  49. package/dist/gexf.js.map +1 -1
  50. package/dist/gml.js +170 -149
  51. package/dist/gml.js.map +1 -1
  52. package/dist/graph-io.js +27 -27
  53. package/dist/graphml.js +2 -2
  54. package/dist/json.js +1 -1
  55. package/dist/neo4j.js +103 -65
  56. package/dist/neo4j.js.map +1 -1
  57. package/dist/obo.js +1 -1
  58. package/dist/pajek.js +1 -1
  59. package/dist/src/children.d.ts.map +1 -1
  60. package/dist/src/children.js +50 -27
  61. package/dist/src/children.js.map +1 -1
  62. package/dist/src/common/attributes.d.ts.map +1 -1
  63. package/dist/src/common/attributes.js +86 -42
  64. package/dist/src/common/attributes.js.map +1 -1
  65. package/dist/src/common/input.d.ts.map +1 -1
  66. package/dist/src/common/input.js +358 -184
  67. package/dist/src/common/input.js.map +1 -1
  68. package/dist/src/common/lists.js +30 -15
  69. package/dist/src/common/lists.js.map +1 -1
  70. package/dist/src/common/text.d.ts +7 -0
  71. package/dist/src/common/text.d.ts.map +1 -1
  72. package/dist/src/common/text.js +15 -7
  73. package/dist/src/common/text.js.map +1 -1
  74. package/dist/src/common/zip.d.ts.map +1 -1
  75. package/dist/src/common/zip.js +36 -19
  76. package/dist/src/common/zip.js.map +1 -1
  77. package/dist/src/formats/csv/exporter.d.ts.map +1 -1
  78. package/dist/src/formats/csv/exporter.js +288 -146
  79. package/dist/src/formats/csv/exporter.js.map +1 -1
  80. package/dist/src/formats/csv/importer.d.ts.map +1 -1
  81. package/dist/src/formats/csv/importer.js +129 -80
  82. package/dist/src/formats/csv/importer.js.map +1 -1
  83. package/dist/src/formats/csv/records.d.ts.map +1 -1
  84. package/dist/src/formats/csv/records.js +78 -36
  85. package/dist/src/formats/csv/records.js.map +1 -1
  86. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  87. package/dist/src/formats/cys/tables.js +11 -8
  88. package/dist/src/formats/cys/tables.js.map +1 -1
  89. package/dist/src/formats/dot/tokenizer.d.ts +39 -0
  90. package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
  91. package/dist/src/formats/dot/tokenizer.js +112 -66
  92. package/dist/src/formats/dot/tokenizer.js.map +1 -1
  93. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  94. package/dist/src/formats/gexf/exporter.js +65 -37
  95. package/dist/src/formats/gexf/exporter.js.map +1 -1
  96. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  97. package/dist/src/formats/gexf/importer.js +138 -50
  98. package/dist/src/formats/gexf/importer.js.map +1 -1
  99. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  100. package/dist/src/formats/gml/exporter.js +51 -35
  101. package/dist/src/formats/gml/exporter.js.map +1 -1
  102. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  103. package/dist/src/formats/gml/importer.js +103 -58
  104. package/dist/src/formats/gml/importer.js.map +1 -1
  105. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  106. package/dist/src/formats/gml/syntax.js +17 -8
  107. package/dist/src/formats/gml/syntax.js.map +1 -1
  108. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  109. package/dist/src/formats/graphml/exporter.js +34 -24
  110. package/dist/src/formats/graphml/exporter.js.map +1 -1
  111. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  112. package/dist/src/formats/graphml/importer.js +17 -13
  113. package/dist/src/formats/graphml/importer.js.map +1 -1
  114. package/dist/src/formats/graphml/tree.js +23 -14
  115. package/dist/src/formats/graphml/tree.js.map +1 -1
  116. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  117. package/dist/src/formats/graphml/yfiles.js +22 -10
  118. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  119. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  120. package/dist/src/formats/json/dialect.js +54 -20
  121. package/dist/src/formats/json/dialect.js.map +1 -1
  122. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  123. package/dist/src/formats/json/exporter.js +38 -21
  124. package/dist/src/formats/json/exporter.js.map +1 -1
  125. package/dist/src/formats/json/importer.d.ts.map +1 -1
  126. package/dist/src/formats/json/importer.js +536 -343
  127. package/dist/src/formats/json/importer.js.map +1 -1
  128. package/dist/src/formats/json/obographs.js +29 -17
  129. package/dist/src/formats/json/obographs.js.map +1 -1
  130. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  131. package/dist/src/formats/neo4j/exporter.js +73 -43
  132. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  133. package/dist/src/formats/neo4j/header.d.ts.map +1 -1
  134. package/dist/src/formats/neo4j/header.js +37 -16
  135. package/dist/src/formats/neo4j/header.js.map +1 -1
  136. package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
  137. package/dist/src/formats/neo4j/importer.js +21 -11
  138. package/dist/src/formats/neo4j/importer.js.map +1 -1
  139. package/dist/src/formats/obo/exporter.d.ts.map +1 -1
  140. package/dist/src/formats/obo/exporter.js +18 -7
  141. package/dist/src/formats/obo/exporter.js.map +1 -1
  142. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  143. package/dist/src/formats/pajek/exporter.js +142 -73
  144. package/dist/src/formats/pajek/exporter.js.map +1 -1
  145. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  146. package/dist/src/formats/pajek/importer.js +26 -15
  147. package/dist/src/formats/pajek/importer.js.map +1 -1
  148. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  149. package/dist/src/formats/pajek/syntax.js +85 -58
  150. package/dist/src/formats/pajek/syntax.js.map +1 -1
  151. package/dist/src/formats/xgmml/emit.d.ts +7 -0
  152. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  153. package/dist/src/formats/xgmml/emit.js +79 -40
  154. package/dist/src/formats/xgmml/emit.js.map +1 -1
  155. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  156. package/dist/src/formats/xgmml/exporter.js +38 -12
  157. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  158. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  159. package/dist/src/formats/xgmml/importer.js +38 -18
  160. package/dist/src/formats/xgmml/importer.js.map +1 -1
  161. package/dist/src/sniff.js +109 -57
  162. package/dist/src/sniff.js.map +1 -1
  163. package/dist/xgmml.js +2 -2
  164. package/package.json +2 -2
  165. package/src/children.ts +54 -27
  166. package/src/common/attributes.ts +118 -49
  167. package/src/common/input.ts +439 -197
  168. package/src/common/lists.ts +29 -15
  169. package/src/common/text.ts +24 -15
  170. package/src/common/zip.ts +47 -18
  171. package/src/formats/csv/exporter.ts +377 -175
  172. package/src/formats/csv/importer.ts +155 -84
  173. package/src/formats/csv/records.ts +90 -35
  174. package/src/formats/cys/tables.ts +11 -10
  175. package/src/formats/dot/tokenizer.ts +118 -68
  176. package/src/formats/gexf/exporter.ts +67 -36
  177. package/src/formats/gexf/importer.ts +173 -63
  178. package/src/formats/gml/exporter.ts +78 -82
  179. package/src/formats/gml/importer.ts +119 -68
  180. package/src/formats/gml/syntax.ts +18 -8
  181. package/src/formats/graphml/exporter.ts +44 -24
  182. package/src/formats/graphml/importer.ts +18 -11
  183. package/src/formats/graphml/tree.ts +22 -12
  184. package/src/formats/graphml/yfiles.ts +23 -10
  185. package/src/formats/json/dialect.ts +61 -22
  186. package/src/formats/json/exporter.ts +40 -21
  187. package/src/formats/json/importer.ts +701 -385
  188. package/src/formats/json/obographs.ts +35 -15
  189. package/src/formats/neo4j/exporter.ts +79 -41
  190. package/src/formats/neo4j/header.ts +50 -16
  191. package/src/formats/neo4j/importer.ts +21 -10
  192. package/src/formats/obo/exporter.ts +34 -17
  193. package/src/formats/pajek/exporter.ts +180 -117
  194. package/src/formats/pajek/importer.ts +27 -15
  195. package/src/formats/pajek/syntax.ts +99 -58
  196. package/src/formats/xgmml/emit.ts +88 -40
  197. package/src/formats/xgmml/exporter.ts +40 -12
  198. package/src/formats/xgmml/importer.ts +45 -23
  199. package/src/sniff.ts +115 -59
  200. package/dist/chunks/children-CL3Cy0ez.js.map +0 -1
  201. package/dist/chunks/export-B-aVCwyG.js.map +0 -1
  202. package/dist/chunks/exporter-BVXnV9-9.js.map +0 -1
  203. package/dist/chunks/exporter-Bcp-l4Bo.js.map +0 -1
  204. package/dist/chunks/importer-AjwOJrn2.js.map +0 -1
  205. package/dist/chunks/importer-BpuS3J8C.js.map +0 -1
  206. package/dist/chunks/importer-CPqnIY8m.js.map +0 -1
  207. package/dist/chunks/importer-DEp_fYjf.js.map +0 -1
  208. package/dist/chunks/importer-DcKB97kW.js.map +0 -1
  209. package/dist/chunks/records-r3SFHz11.js.map +0 -1
  210. package/dist/chunks/text-Bjfa1xYL.js.map +0 -1
@@ -144,21 +144,9 @@ function splitBracketed(text: string): string[] {
144
144
  }
145
145
  let item = "";
146
146
  if (i < n && (inner[i] === '"' || inner[i] === "'")) {
147
- const quote = inner[i];
148
- i++;
149
- while (i < n) {
150
- if (inner[i] === quote) {
151
- if (inner[i + 1] === quote) {
152
- item += quote;
153
- i += 2;
154
- continue;
155
- }
156
- i++;
157
- break;
158
- }
159
- item += inner[i];
160
- i++;
161
- }
147
+ const quoted = readQuoted(inner, i);
148
+ item = quoted.text;
149
+ i = quoted.end;
162
150
  }
163
151
  // unquoted text, or text after a closing quote that is not a separator, runs to the next comma
164
152
  let end = inner.indexOf(",", i);
@@ -179,6 +167,32 @@ function splitBracketed(text: string): string[] {
179
167
  }
180
168
  }
181
169
 
170
+ /**
171
+ * Read a quoted item of a bracketed list: a doubled quote inside it is one quote, and a missing
172
+ * closing quote ends it at the end of the text.
173
+ * @param inner - the inside of the brackets
174
+ * @param open - the index of the opening quote
175
+ * @returns the unquoted text and the index just past the closing quote
176
+ */
177
+ function readQuoted(inner: string, open: number): { text: string; end: number } {
178
+ const quote = inner[open];
179
+ const n = inner.length;
180
+ let text = "";
181
+ let i = open + 1;
182
+ while (i < n) {
183
+ if (inner[i] !== quote) {
184
+ text += inner[i];
185
+ i++;
186
+ } else if (inner[i + 1] === quote) {
187
+ text += quote;
188
+ i += 2;
189
+ } else {
190
+ return { text, end: i + 1 };
191
+ }
192
+ }
193
+ return { text, end: i };
194
+ }
195
+
182
196
  /**
183
197
  * Whether a char code is ASCII whitespace.
184
198
  * @param c - the char code
@@ -202,21 +202,7 @@ export class TextCellWriter {
202
202
  write(row: number, text: string): void {
203
203
  const kind = inferTextDtype(text);
204
204
  const value = parseTextCell(text);
205
- if (
206
- typeof value === "number" &&
207
- !Number.isSafeInteger(value) &&
208
- I32_TEXT.test(text) &&
209
- BigInt(text) !== BigInt(value)
210
- ) {
211
- // an integer beyond 2^53 is stored as the nearest double; say so once per column
212
- this.report.warnOnce(
213
- "precision",
214
- PRECISION_CODE,
215
- `${this.domain} column "${this.name}": integers beyond 2^53 are stored as the nearest double (first: ${text})`,
216
- { element: this.name },
217
- `${PRECISION_CODE}:${this.domain}:${this.name}`,
218
- );
219
- }
205
+ this.warnIfImprecise(text, value);
220
206
  const wasString = this.textDtype === "string";
221
207
  const textDtype =
222
208
  this.textDtype === null || textDtypeRank(kind) > textDtypeRank(this.textDtype) ? kind : this.textDtype;
@@ -250,6 +236,29 @@ export class TextCellWriter {
250
236
  }
251
237
  }
252
238
 
239
+ /**
240
+ * Warn, once per column, when the cell is an integer beyond 2^53 that is stored as the nearest
241
+ * double.
242
+ * @param text - the cell text
243
+ * @param value - the parsed value
244
+ */
245
+ private warnIfImprecise(text: string, value: unknown): void {
246
+ if (
247
+ typeof value === "number" &&
248
+ !Number.isSafeInteger(value) &&
249
+ I32_TEXT.test(text) &&
250
+ BigInt(text) !== BigInt(value)
251
+ ) {
252
+ this.report.warnOnce(
253
+ "precision",
254
+ PRECISION_CODE,
255
+ `${this.domain} column "${this.name}": integers beyond 2^53 are stored as the nearest double (first: ${text})`,
256
+ { element: this.name },
257
+ `${PRECISION_CODE}:${this.domain}:${this.name}`,
258
+ );
259
+ }
260
+ }
261
+
253
262
  /**
254
263
  * Write a value (the parsed scalar, or a text into a widened column).
255
264
  * @param row - the row
package/src/common/zip.ts CHANGED
@@ -134,6 +134,52 @@ export function startsLikeZip(bytes: Uint8Array): boolean {
134
134
  return bytes.byteLength >= 4 && bytes[0] === 0x50 && bytes[1] === 0x4b && bytes[2] === 3 && bytes[3] === 4;
135
135
  }
136
136
 
137
+ /**
138
+ * Read the end of central directory record, following the zip64 locator when there is one.
139
+ * @param view - the whole archive
140
+ * @param eocd - the offset of the end record
141
+ * @returns the disk numbers, the entry count and where the central directory is; ZipError
142
+ * "corrupt" when the end record needs a zip64 record the archive does not have
143
+ */
144
+ function readEndRecord(
145
+ view: DataView,
146
+ eocd: number,
147
+ ): {
148
+ disk: number;
149
+ directoryDisk: number;
150
+ count: number;
151
+ directorySize: number;
152
+ directoryOffset: number;
153
+ directoryEnd: number;
154
+ } {
155
+ const locator = eocd - ZIP64_LOCATOR_SIZE;
156
+ if (locator >= 0 && view.getUint32(locator, true) === ZIP64_LOCATOR_SIGNATURE) {
157
+ const record = zip64EndRecord(view, locator);
158
+ return {
159
+ disk: view.getUint32(record + 16, true),
160
+ directoryDisk: view.getUint32(record + 20, true),
161
+ count: readU64(view, record + 32),
162
+ directorySize: readU64(view, record + 40),
163
+ directoryOffset: readU64(view, record + 48),
164
+ directoryEnd: record,
165
+ };
166
+ }
167
+ const count = view.getUint16(eocd + 10, true);
168
+ const directorySize = view.getUint32(eocd + 12, true);
169
+ const directoryOffset = view.getUint32(eocd + 16, true);
170
+ if (count === U16_MAX || directorySize === U32_MAX || directoryOffset === U32_MAX) {
171
+ throw new ZipError("corrupt", "the end record needs a zip64 record the archive does not have");
172
+ }
173
+ return {
174
+ disk: view.getUint16(eocd + 4, true),
175
+ directoryDisk: view.getUint16(eocd + 6, true),
176
+ count,
177
+ directorySize,
178
+ directoryOffset,
179
+ directoryEnd: eocd,
180
+ };
181
+ }
182
+
137
183
  /**
138
184
  * Read the central directory.
139
185
  * @param bytes - the whole archive
@@ -150,24 +196,7 @@ export function readZipDirectory(bytes: Uint8Array): ZipEntry[] {
150
196
  ? new ZipError("corrupt", "the archive has no end of central directory record (truncated?)")
151
197
  : new ZipError("not-zip", "the input is not a zip archive");
152
198
  }
153
- let disk = view.getUint16(eocd + 4, true);
154
- let directoryDisk = view.getUint16(eocd + 6, true);
155
- let count = view.getUint16(eocd + 10, true);
156
- let directorySize = view.getUint32(eocd + 12, true);
157
- let directoryOffset = view.getUint32(eocd + 16, true);
158
- let directoryEnd = eocd;
159
- const locator = eocd - ZIP64_LOCATOR_SIZE;
160
- if (locator >= 0 && view.getUint32(locator, true) === ZIP64_LOCATOR_SIGNATURE) {
161
- const record = zip64EndRecord(view, locator);
162
- disk = view.getUint32(record + 16, true);
163
- directoryDisk = view.getUint32(record + 20, true);
164
- count = readU64(view, record + 32);
165
- directorySize = readU64(view, record + 40);
166
- directoryOffset = readU64(view, record + 48);
167
- directoryEnd = record;
168
- } else if (count === U16_MAX || directorySize === U32_MAX || directoryOffset === U32_MAX) {
169
- throw new ZipError("corrupt", "the end record needs a zip64 record the archive does not have");
170
- }
199
+ const { disk, directoryDisk, count, directorySize, directoryOffset, directoryEnd } = readEndRecord(view, eocd);
171
200
  if (disk !== 0 || directoryDisk !== 0) {
172
201
  throw new ZipError("unsupported", "a split (multi-disk) archive cannot be read");
173
202
  }