@graphty/graph-io 0.3.4 → 0.3.5

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 (50) hide show
  1. package/dist/chunks/{escape-DXbOoLKl.js → escape-BjmIaFFo.js} +2 -2
  2. package/dist/chunks/{escape-DXbOoLKl.js.map → escape-BjmIaFFo.js.map} +1 -1
  3. package/dist/chunks/{importer-B9qF4e32.js → importer-BddBW3sf.js} +2 -2
  4. package/dist/chunks/{importer-B9qF4e32.js.map → importer-BddBW3sf.js.map} +1 -1
  5. package/dist/chunks/{importer-xoHpRG5x.js → importer-BtHFICnf.js} +2 -2
  6. package/dist/chunks/{importer-xoHpRG5x.js.map → importer-BtHFICnf.js.map} +1 -1
  7. package/dist/chunks/{importer-C2caVvl6.js → importer-DfI8POXb.js} +272 -63
  8. package/dist/chunks/importer-DfI8POXb.js.map +1 -0
  9. package/dist/csv.js +1 -1
  10. package/dist/dot.js +1 -1
  11. package/dist/gexf.js +1 -1
  12. package/dist/gml.js +1 -1
  13. package/dist/graph-io.js +9 -8
  14. package/dist/graphml.js +1 -1
  15. package/dist/neo4j.js +51 -16
  16. package/dist/neo4j.js.map +1 -1
  17. package/dist/pajek.js +1 -1
  18. package/dist/src/common/escape.d.ts +4 -3
  19. package/dist/src/common/escape.d.ts.map +1 -1
  20. package/dist/src/common/escape.js +5 -4
  21. package/dist/src/common/escape.js.map +1 -1
  22. package/dist/src/formats/neo4j/exporter.d.ts +3 -1
  23. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  24. package/dist/src/formats/neo4j/exporter.js +34 -6
  25. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  26. package/dist/src/formats/neo4j/importer.d.ts +16 -3
  27. package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
  28. package/dist/src/formats/neo4j/importer.js +49 -11
  29. package/dist/src/formats/neo4j/importer.js.map +1 -1
  30. package/dist/src/formats/neo4j/index.d.ts +3 -3
  31. package/dist/src/formats/neo4j/index.d.ts.map +1 -1
  32. package/dist/src/formats/neo4j/index.js +3 -3
  33. package/dist/src/formats/neo4j/index.js.map +1 -1
  34. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  35. package/dist/src/formats/pajek/exporter.js +3 -2
  36. package/dist/src/formats/pajek/exporter.js.map +1 -1
  37. package/dist/src/formats/pajek/importer.d.ts +14 -8
  38. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  39. package/dist/src/formats/pajek/importer.js +233 -61
  40. package/dist/src/formats/pajek/importer.js.map +1 -1
  41. package/dist/src/formats/pajek/syntax.d.ts +39 -8
  42. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  43. package/dist/src/formats/pajek/syntax.js +81 -11
  44. package/dist/src/formats/pajek/syntax.js.map +1 -1
  45. package/dist/src/index.d.ts +1 -1
  46. package/dist/src/index.d.ts.map +1 -1
  47. package/dist/src/index.js +1 -1
  48. package/dist/src/index.js.map +1 -1
  49. package/package.json +2 -2
  50. package/dist/chunks/importer-C2caVvl6.js.map +0 -1
package/dist/neo4j.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { X as ROLE_TAKEN_CODE$1, o as ID_MERGED_CODE$1, k as DUPLICATE_NODE_CODE$1, M as MISSING_ENDPOINT_CODE$1, y as MISSING_ID_CODE$1, aF as resolveImportOptions, I as ImportReportBuilder, aC as reportSinkOptions, aD as reportUnusedOptions, a as throwIfAborted, v as IdCoercer, l as DirectionResolver, w as ImportError, aO as declareAttribute, b1 as declareOn, aL as uniqueColumnName, U as RENAMED_CODE, aA as parseWeightText, aP as parseDeclaredTemporal, aQ as parseDeclaredValue, aR as losesPrecision, ah as declareCompanion, T as PRECISION_CODE, aT as splitListText, au as isImportInput, b0 as takenIn, ar as inputLength, ac as capabilities, p as ID_TEXT_COLLISION_CODE, q as ID_TEXT_TYPE_CODE, ax as joinText, ak as encodeChunks, aE as resolveExportOptions, ad as checkCapabilities, az as pairFolding, L as LOSS, aX as mapDeclaredType, al as explicitWeights, at as isCanonicalIntegerText, aZ as formatTemporal, ao as formatF64, an as formatF32, aq as formatInteger, Y as SINK_OPTION_CODE, P as OPTION_IGNORED_CODE, C as COLUMN_RENAMED_CODE, a3 as UNKNOWN_ATTR_TYPE_CODE, a5 as UNKNOWN_ENCODING_CODE, n as ENCODING_FALLBACK_CODE, s as INVALID_ENCODING_CODE, u as INVALID_UTF8_CODE, a8 as WEIGHT_KEY_CLASH_CODE, W as ROLE_DROPPED_CODE, J as MUTUAL_EXPANDED_CODE } from "./chunks/writer-BdMak4_J.js";
2
2
  import { c as checkRecordSyntax, R as RecordReader, B as BAD_QUOTE_CODE, U as UNCLOSED_QUOTE_CODE } from "./chunks/records-BKSMowhR.js";
3
3
  import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
4
- import { n as quoteCsvCell } from "./chunks/escape-DXbOoLKl.js";
4
+ import { n as quoteCsvCell } from "./chunks/escape-BjmIaFFo.js";
5
5
  const STRUCTURAL = /* @__PURE__ */ new Set(["ID", "LABEL", "START_ID", "END_ID", "TYPE", "IGNORE"]);
6
6
  const SPACE_KINDS = /* @__PURE__ */ new Set(["ID", "START_ID", "END_ID"]);
7
7
  const HEADER_MARKER = /^[^:{}()]*:\s*(ID|START_ID|END_ID)\s*(\(|\{|$)/i;
@@ -89,6 +89,7 @@ function formatHeaderField(name, type, space) {
89
89
  const LABELS_COLUMN = "labels";
90
90
  const TYPE_COLUMN = "type";
91
91
  const ID_SPACE_COLUMN = "idSpace";
92
+ const ORIGINAL_ID_COLUMN = "originalId";
92
93
  const HEADER_CODE = "E_NEO4J_HEADER";
93
94
  const COLUMN_COUNT_CODE = "E_NEO4J_COLUMN_COUNT";
94
95
  const MISSING_ID_CODE = MISSING_ID_CODE$1;
@@ -137,6 +138,13 @@ const ID_SPACE_DECL = {
137
138
  role: "idSpace",
138
139
  origin: { format: NEO4J$1, id: ":ID", title: null, type: "ID", namespace: null }
139
140
  };
141
+ const ORIGINAL_ID_DECL = {
142
+ name: ORIGINAL_ID_COLUMN,
143
+ dtype: "string",
144
+ nullable: true,
145
+ // origin.type stays null so the column is never mistaken for a stored id (`name:ID`)
146
+ origin: { format: NEO4J$1, id: ":ID", title: null, type: null, namespace: null }
147
+ };
140
148
  const ARRAY_DELIMITERS = { ";": "semicolon", ",": "comma", "|": "pipe" };
141
149
  const NEO4J_DELIMITER_CANDIDATES = Object.freeze([",", " "]);
142
150
  function resolveNeo4jOptions(options) {
@@ -291,6 +299,7 @@ class Neo4jImportSession {
291
299
  this.labelsHandle = INVALID_INDEX;
292
300
  this.typeHandle = INVALID_INDEX;
293
301
  this.idSpaceHandle = INVALID_INDEX;
302
+ this.originalIdHandle = INVALID_INDEX;
294
303
  this.ignoredColumns = 0;
295
304
  this.headerSet = false;
296
305
  this.values = [];
@@ -510,6 +519,8 @@ class Neo4jImportSession {
510
519
  width: fields.length,
511
520
  startCell,
512
521
  endCell,
522
+ startSpace,
523
+ endSpace,
513
524
  startSpaceCode: startSpace === null ? 0 : this.registry.codeOf(startSpace),
514
525
  endSpaceCode: endSpace === null ? 0 : this.registry.codeOf(endSpace),
515
526
  typeCell,
@@ -603,6 +614,7 @@ class Neo4jImportSession {
603
614
  ensureIdSpace() {
604
615
  if (this.idSpaceHandle === INVALID_INDEX) {
605
616
  this.idSpaceHandle = this.declareReserved("node", ID_SPACE_DECL);
617
+ this.originalIdHandle = this.declareReserved("node", ORIGINAL_ID_DECL);
606
618
  }
607
619
  }
608
620
  /**
@@ -672,11 +684,12 @@ class Neo4jImportSession {
672
684
  report.counts.skippedNodes++;
673
685
  return;
674
686
  }
675
- const id = this.coerceId(idText2, line);
676
- if (id === null || !this.parseProperties(section.properties, cells, quoted, line, idText2)) {
687
+ const coerced = this.coerceId(idText2, line);
688
+ if (coerced === null || !this.parseProperties(section.properties, cells, quoted, line, idText2)) {
677
689
  report.counts.skippedNodes++;
678
690
  return;
679
691
  }
692
+ const id = qualify(coerced, section.space);
680
693
  let labels;
681
694
  if (section.labelCells.length > 0 || section.extraLabels.length > 0) {
682
695
  labels = this.labelsOf(section, cells, quoted);
@@ -709,6 +722,7 @@ class Neo4jImportSession {
709
722
  }
710
723
  if (section.space !== null) {
711
724
  sink.setNodeValue(this.idSpaceHandle, index, section.space);
725
+ sink.setNodeValue(this.originalIdHandle, index, idText2);
712
726
  }
713
727
  if (labels !== void 0) {
714
728
  sink.setNodeValue(this.labelsHandle, index, labels);
@@ -756,12 +770,14 @@ class Neo4jImportSession {
756
770
  return;
757
771
  }
758
772
  const element = `${startText}->${endText}`;
759
- const source = this.coerceId(startText, line);
760
- const target = source === null ? null : this.coerceId(endText, line);
761
- if (source === null || target === null) {
773
+ const start = this.coerceId(startText, line);
774
+ const end = start === null ? null : this.coerceId(endText, line);
775
+ if (start === null || end === null) {
762
776
  report.counts.skippedEdges++;
763
777
  return;
764
778
  }
779
+ const source = qualify(start, section.startSpace);
780
+ const target = qualify(end, section.endSpace);
765
781
  let wrongSpace = null;
766
782
  if (this.wrongSpace(source, section.startSpaceCode)) {
767
783
  wrongSpace = startText;
@@ -811,9 +827,9 @@ class Neo4jImportSession {
811
827
  report.counts.edges++;
812
828
  }
813
829
  /**
814
- * Whether an endpoint id belongs to a node a node row declared in another id space than the
815
- * endpoint's header declares. An endpoint without a declared space, or a node no row declared
816
- * yet, is looked up by id alone.
830
+ * Whether a qualified endpoint id belongs to a node a node row declared in another id space than
831
+ * the endpoint's header declares (an unspaced node whose id text is `Space:id`). An endpoint
832
+ * without a declared space, or a node no row declared yet, is looked up by id alone.
817
833
  * @param id - the endpoint id
818
834
  * @param spaceCode - the endpoint's space code, 0 for none
819
835
  * @returns true when the endpoint resolves to a node of another space
@@ -972,6 +988,9 @@ class Neo4jImportSession {
972
988
  return labels;
973
989
  }
974
990
  }
991
+ function qualify(id, space) {
992
+ return space === null ? id : `${space}:${String(id)}`;
993
+ }
975
994
  function emptyValue(spec) {
976
995
  if (spec.list) {
977
996
  return [];
@@ -1163,6 +1182,7 @@ class ExportPlan {
1163
1182
  this.options = options;
1164
1183
  this.common = common;
1165
1184
  this.idSpace = snapshot.nodes.byRole("idSpace");
1185
+ this.originalId = [...snapshot.nodes].find((column) => isIdText(column.meta)) ?? null;
1166
1186
  this.labels = snapshot.nodes.byRole("labels");
1167
1187
  this.kind = snapshot.edges.byRole("kind");
1168
1188
  for (const column of snapshot.nodes) {
@@ -1285,7 +1305,7 @@ class ExportPlan {
1285
1305
  if (companions.has(column) || role !== null && SKIPPED_ROLES.has(role)) {
1286
1306
  continue;
1287
1307
  }
1288
- if (domain === "node" && (isStoredId(meta) || column === this.idSpace || column === this.labels)) {
1308
+ if (domain === "node" && (isStoredId(meta) || column === this.idSpace || column === this.labels || column === this.originalId)) {
1289
1309
  continue;
1290
1310
  }
1291
1311
  if (domain === "edge" && (role === "id" || column === this.kind)) {
@@ -1657,6 +1677,19 @@ class ExportPlan {
1657
1677
  const value = idSpace.value(index);
1658
1678
  return typeof value === "string" ? value : String(value);
1659
1679
  }
1680
+ /**
1681
+ * The `:ID` / `:START_ID` / `:END_ID` text of a node: its originalId value when it has an id
1682
+ * space (the importer stored it as `Space:id`), its id otherwise.
1683
+ * @param index - the node index
1684
+ * @returns the id text
1685
+ */
1686
+ idTextOf(index) {
1687
+ const { originalId } = this;
1688
+ if (originalId !== null && originalId.isSet(index) && this.spaceOf(index) !== null) {
1689
+ return textOf(originalId, index);
1690
+ }
1691
+ return idText(this.snapshot.ids.idOf(index));
1692
+ }
1660
1693
  /**
1661
1694
  * The stored-id column of a node: the first one set in declaration order.
1662
1695
  * @param index - the node index
@@ -1694,7 +1727,6 @@ class ExportPlan {
1694
1727
  */
1695
1728
  *nodeLines() {
1696
1729
  const { snapshot, labels, nodeColumns } = this;
1697
- const { ids } = snapshot;
1698
1730
  const { delimiter } = this.options.syntax;
1699
1731
  const propertyHeaders = nodeColumns.map((plan2) => plan2.header).join(delimiter);
1700
1732
  let sections = 0;
@@ -1720,7 +1752,7 @@ class ExportPlan {
1720
1752
  `;
1721
1753
  }
1722
1754
  cells.length = 0;
1723
- cells.push(this.cell(idText(ids.idOf(i))));
1755
+ cells.push(this.cell(this.idTextOf(i)));
1724
1756
  if (labels !== null) {
1725
1757
  cells.push(this.cell(this.labelsText(i)));
1726
1758
  }
@@ -1749,7 +1781,6 @@ class ExportPlan {
1749
1781
  */
1750
1782
  *relationshipLines() {
1751
1783
  const { snapshot, kind, weights, edgeColumns, folding } = this;
1752
- const { ids } = snapshot;
1753
1784
  const { delimiter } = this.options.syntax;
1754
1785
  const list = snapshot.edgeList();
1755
1786
  const propertyHeaders = edgeColumns.map((plan2) => plan2.header).join(delimiter);
@@ -1787,7 +1818,7 @@ class ExportPlan {
1787
1818
  yield headerOf(startSpace, endSpace);
1788
1819
  }
1789
1820
  cells.length = 0;
1790
- cells.push(this.cell(idText(ids.idOf(u))), this.cell(idText(ids.idOf(v))));
1821
+ cells.push(this.cell(this.idTextOf(u)), this.cell(this.idTextOf(v)));
1791
1822
  if (kind !== null) {
1792
1823
  cells.push(this.cell(kind.isSet(e) ? textOf(kind, e) : null));
1793
1824
  }
@@ -1864,6 +1895,9 @@ class ExportPlan {
1864
1895
  return formatScalar(column.dtype === "json" ? column.values[row] : column.value(row), scalar, text);
1865
1896
  }
1866
1897
  }
1898
+ function isIdText(meta) {
1899
+ return meta.role === null && meta.dtype === "string" && meta.origin !== null && meta.origin.format === NEO4J && meta.origin.id === ":ID" && meta.origin.type === null;
1900
+ }
1867
1901
  function isStoredId(meta) {
1868
1902
  return meta.role === null && meta.dtype === "string" && meta.origin !== null && meta.origin.format === NEO4J && meta.origin.type === ID_TYPE;
1869
1903
  }
@@ -2050,9 +2084,9 @@ const NEO4J_ISSUE = Object.freeze({
2050
2084
  MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,
2051
2085
  /** A node id repeated in one id space (last write wins). */
2052
2086
  DUPLICATE_NODE: DUPLICATE_NODE_CODE,
2053
- /** A node id declared in two id spaces. */
2087
+ /** A spaced node id `Space:id` that equals the text of an id declared without a space. */
2054
2088
  ID_SPACE_COLLISION: ID_SPACE_COLLISION_CODE,
2055
- /** A relationship endpoint whose id belongs to a node of another id space; the row is skipped. */
2089
+ /** A spaced relationship endpoint `Space:id` that names a node declared without a space; the row is skipped. */
2056
2090
  ENDPOINT_SPACE: ENDPOINT_SPACE_CODE,
2057
2091
  /** Two id texts merged into one number under ids "number". */
2058
2092
  ID_MERGED: ID_MERGED_CODE,
@@ -2103,6 +2137,7 @@ export {
2103
2137
  NEO4J_CAPABILITIES,
2104
2138
  NEO4J_ISSUE,
2105
2139
  NEO4J_LOSS,
2140
+ ORIGINAL_ID_COLUMN,
2106
2141
  TYPE_COLUMN,
2107
2142
  neo4jExporter,
2108
2143
  neo4jImporter