@graphty/graph-io 0.3.24 → 0.3.26
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.
- package/README.md +49 -414
- package/dist/chunks/children-CL3Cy0ez.js.map +1 -1
- package/dist/chunks/choose-BbJI55dx.js +56 -0
- package/dist/chunks/choose-BbJI55dx.js.map +1 -0
- package/dist/chunks/constants-BCsFsMj4.js +231 -0
- package/dist/chunks/constants-BCsFsMj4.js.map +1 -0
- package/dist/chunks/{escape-B-tkk_Cl.js → escape-D0g6NNUy.js} +382 -92
- package/dist/chunks/escape-D0g6NNUy.js.map +1 -0
- package/dist/chunks/export-BTI4yQgy.js +4333 -0
- package/dist/chunks/export-BTI4yQgy.js.map +1 -0
- package/dist/chunks/exporter-BMqk5oxW.js +3465 -0
- package/dist/chunks/exporter-BMqk5oxW.js.map +1 -0
- package/dist/chunks/{importer-eUREhBGj.js → exporter-Cra2GYcN.js} +4969 -3201
- package/dist/chunks/exporter-Cra2GYcN.js.map +1 -0
- package/dist/chunks/{exporter-BGrsWamJ.js → exporter-Dxh231ZF.js} +38 -229
- package/dist/chunks/exporter-Dxh231ZF.js.map +1 -0
- package/dist/chunks/{exporter-DIeGJXAZ.js → exporter-tne475KK.js} +22 -20
- package/dist/chunks/exporter-tne475KK.js.map +1 -0
- package/dist/chunks/importer-90YWhJoF.js +2811 -0
- package/dist/chunks/importer-90YWhJoF.js.map +1 -0
- package/dist/chunks/{importer-D_e7e7LX.js → importer-Bcl1d4xH.js} +398 -145
- package/dist/chunks/importer-Bcl1d4xH.js.map +1 -0
- package/dist/chunks/{importer-BWY2FFc5.js → importer-BfIsp1f9.js} +255 -77
- package/dist/chunks/importer-BfIsp1f9.js.map +1 -0
- package/dist/chunks/{importer-zGLo8Dg_.js → importer-C_TEA1zJ.js} +484 -157
- package/dist/chunks/importer-C_TEA1zJ.js.map +1 -0
- package/dist/chunks/{importer-DET1tg6s.js → importer-DCjOvO7U.js} +1687 -310
- package/dist/chunks/importer-DCjOvO7U.js.map +1 -0
- package/dist/chunks/{importer-vi3bSdtw.js → importer-DfVu6j59.js} +509 -76
- package/dist/chunks/importer-DfVu6j59.js.map +1 -0
- package/dist/chunks/{importer-DIrbbnAf.js → importer-Dku_VAIY.js} +585 -226
- package/dist/chunks/importer-Dku_VAIY.js.map +1 -0
- package/dist/chunks/json-elements-3tnyt5uZ.js +1225 -0
- package/dist/chunks/json-elements-3tnyt5uZ.js.map +1 -0
- package/dist/chunks/ontology-export-B9Tcf37D.js +357 -0
- package/dist/chunks/ontology-export-B9Tcf37D.js.map +1 -0
- package/dist/chunks/{records-dbRkxwaq.js → records-CQXT__mY.js} +298 -114
- package/dist/chunks/records-CQXT__mY.js.map +1 -0
- package/dist/chunks/{text-Dr0Ifpag.js → text-DmcUs5_Q.js} +29 -11
- package/dist/chunks/text-DmcUs5_Q.js.map +1 -0
- package/dist/chunks/{writer-C7flM-Ih.js → writer-DxjgHwSe.js} +19 -1
- package/dist/chunks/writer-DxjgHwSe.js.map +1 -0
- package/dist/csv.js +951 -261
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +6 -3
- package/dist/cx2.js +2 -2
- package/dist/cys.js +6 -3
- package/dist/dot.js +1 -1
- package/dist/gexf.js +554 -122
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +342 -85
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +1105 -213
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +3 -2
- package/dist/graphml.js.map +1 -1
- package/dist/json.js +3 -2
- package/dist/neo4j.js +564 -157
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +6 -3
- package/dist/pajek.js +1 -1
- package/dist/src/children.d.ts +18 -6
- package/dist/src/children.d.ts.map +1 -1
- package/dist/src/children.js +6 -3
- package/dist/src/children.js.map +1 -1
- package/dist/src/common/attributes.d.ts +29 -11
- package/dist/src/common/attributes.d.ts.map +1 -1
- package/dist/src/common/attributes.js +25 -7
- package/dist/src/common/attributes.js.map +1 -1
- package/dist/src/common/cell-budget.d.ts +9 -2
- package/dist/src/common/cell-budget.d.ts.map +1 -1
- package/dist/src/common/cell-budget.js +11 -3
- package/dist/src/common/cell-budget.js.map +1 -1
- package/dist/src/common/choose.d.ts +19 -0
- package/dist/src/common/choose.d.ts.map +1 -0
- package/dist/src/common/choose.js +72 -0
- package/dist/src/common/choose.js.map +1 -0
- package/dist/src/common/codes.d.ts +456 -66
- package/dist/src/common/codes.d.ts.map +1 -1
- package/dist/src/common/codes.js +458 -66
- package/dist/src/common/codes.js.map +1 -1
- package/dist/src/common/compare.d.ts +81 -0
- package/dist/src/common/compare.d.ts.map +1 -0
- package/dist/src/common/compare.js +394 -0
- package/dist/src/common/compare.js.map +1 -0
- package/dist/src/common/cx-export.d.ts +123 -0
- package/dist/src/common/cx-export.d.ts.map +1 -0
- package/dist/src/common/cx-export.js +334 -0
- package/dist/src/common/cx-export.js.map +1 -0
- package/dist/src/common/declared-types.d.ts +22 -2
- package/dist/src/common/declared-types.d.ts.map +1 -1
- package/dist/src/common/declared-types.js +19 -1
- package/dist/src/common/declared-types.js.map +1 -1
- package/dist/src/common/direction.d.ts +74 -50
- package/dist/src/common/direction.d.ts.map +1 -1
- package/dist/src/common/direction.js +47 -27
- package/dist/src/common/direction.js.map +1 -1
- package/dist/src/common/escape.d.ts +21 -9
- package/dist/src/common/escape.d.ts.map +1 -1
- package/dist/src/common/escape.js +33 -17
- package/dist/src/common/escape.js.map +1 -1
- package/dist/src/common/export.d.ts +144 -32
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +216 -42
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/format.d.ts +23 -1
- package/dist/src/common/format.d.ts.map +1 -1
- package/dist/src/common/format.js +26 -1
- package/dist/src/common/format.js.map +1 -1
- package/dist/src/common/ids.d.ts +9 -2
- package/dist/src/common/ids.d.ts.map +1 -1
- package/dist/src/common/ids.js +6 -2
- package/dist/src/common/ids.js.map +1 -1
- package/dist/src/common/input.d.ts +122 -28
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +890 -124
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/json-elements.d.ts +144 -20
- package/dist/src/common/json-elements.d.ts.map +1 -1
- package/dist/src/common/json-elements.js +868 -188
- package/dist/src/common/json-elements.js.map +1 -1
- package/dist/src/common/line-format.d.ts +90 -0
- package/dist/src/common/line-format.d.ts.map +1 -0
- package/dist/src/common/line-format.js +185 -0
- package/dist/src/common/line-format.js.map +1 -0
- package/dist/src/common/lists.d.ts +6 -1
- package/dist/src/common/lists.d.ts.map +1 -1
- package/dist/src/common/lists.js +2 -0
- package/dist/src/common/lists.js.map +1 -1
- package/dist/src/common/ontology-export.d.ts +167 -0
- package/dist/src/common/ontology-export.d.ts.map +1 -0
- package/dist/src/common/ontology-export.js +359 -0
- package/dist/src/common/ontology-export.js.map +1 -0
- package/dist/src/common/ontology.d.ts +25 -3
- package/dist/src/common/ontology.d.ts.map +1 -1
- package/dist/src/common/ontology.js +30 -9
- package/dist/src/common/ontology.js.map +1 -1
- package/dist/src/common/options.d.ts +62 -12
- package/dist/src/common/options.d.ts.map +1 -1
- package/dist/src/common/options.js +89 -11
- package/dist/src/common/options.js.map +1 -1
- package/dist/src/common/plural.d.ts +31 -0
- package/dist/src/common/plural.d.ts.map +1 -0
- package/dist/src/common/plural.js +46 -0
- package/dist/src/common/plural.js.map +1 -0
- package/dist/src/common/report.d.ts +72 -14
- package/dist/src/common/report.d.ts.map +1 -1
- package/dist/src/common/report.js +146 -22
- package/dist/src/common/report.js.map +1 -1
- package/dist/src/common/temporal.d.ts +22 -5
- package/dist/src/common/temporal.d.ts.map +1 -1
- package/dist/src/common/temporal.js +13 -2
- package/dist/src/common/temporal.js.map +1 -1
- package/dist/src/common/text.d.ts +39 -23
- package/dist/src/common/text.d.ts.map +1 -1
- package/dist/src/common/text.js +51 -21
- package/dist/src/common/text.js.map +1 -1
- package/dist/src/common/weights.d.ts +37 -4
- package/dist/src/common/weights.d.ts.map +1 -1
- package/dist/src/common/weights.js +61 -2
- package/dist/src/common/weights.js.map +1 -1
- package/dist/src/common/writer.d.ts +19 -3
- package/dist/src/common/writer.d.ts.map +1 -1
- package/dist/src/common/writer.js +30 -2
- package/dist/src/common/writer.js.map +1 -1
- package/dist/src/common/xml.d.ts +125 -9
- package/dist/src/common/xml.d.ts.map +1 -1
- package/dist/src/common/xml.js +400 -83
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/common/zip.d.ts +44 -4
- package/dist/src/common/zip.d.ts.map +1 -1
- package/dist/src/common/zip.js +134 -5
- package/dist/src/common/zip.js.map +1 -1
- package/dist/src/formats/csv/exporter.d.ts +80 -24
- package/dist/src/formats/csv/exporter.d.ts.map +1 -1
- package/dist/src/formats/csv/exporter.js +145 -32
- package/dist/src/formats/csv/exporter.js.map +1 -1
- package/dist/src/formats/csv/header.d.ts +38 -9
- package/dist/src/formats/csv/header.d.ts.map +1 -1
- package/dist/src/formats/csv/header.js +46 -10
- package/dist/src/formats/csv/header.js.map +1 -1
- package/dist/src/formats/csv/importer.d.ts +187 -37
- package/dist/src/formats/csv/importer.d.ts.map +1 -1
- package/dist/src/formats/csv/importer.js +835 -204
- package/dist/src/formats/csv/importer.js.map +1 -1
- package/dist/src/formats/csv/index.d.ts +100 -19
- package/dist/src/formats/csv/index.d.ts.map +1 -1
- package/dist/src/formats/csv/index.js +94 -21
- package/dist/src/formats/csv/index.js.map +1 -1
- package/dist/src/formats/csv/records.d.ts +95 -10
- package/dist/src/formats/csv/records.d.ts.map +1 -1
- package/dist/src/formats/csv/records.js +333 -122
- package/dist/src/formats/csv/records.js.map +1 -1
- package/dist/src/formats/csv/values.d.ts +1 -0
- package/dist/src/formats/csv/values.d.ts.map +1 -1
- package/dist/src/formats/csv/values.js +1 -0
- package/dist/src/formats/csv/values.js.map +1 -1
- package/dist/src/formats/cx/exporter.d.ts +102 -0
- package/dist/src/formats/cx/exporter.d.ts.map +1 -0
- package/dist/src/formats/cx/exporter.js +1217 -0
- package/dist/src/formats/cx/exporter.js.map +1 -0
- package/dist/src/formats/cx/importer.d.ts +79 -32
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +680 -285
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx/index.d.ts +4 -3
- package/dist/src/formats/cx/index.d.ts.map +1 -1
- package/dist/src/formats/cx/index.js +4 -3
- package/dist/src/formats/cx/index.js.map +1 -1
- package/dist/src/formats/cx2/exporter.d.ts +29 -11
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +39 -268
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts +78 -28
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +226 -79
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cx2/index.d.ts +2 -1
- package/dist/src/formats/cx2/index.d.ts.map +1 -1
- package/dist/src/formats/cx2/index.js +2 -1
- package/dist/src/formats/cx2/index.js.map +1 -1
- package/dist/src/formats/cys/constants.d.ts +66 -17
- package/dist/src/formats/cys/constants.d.ts.map +1 -1
- package/dist/src/formats/cys/constants.js +59 -18
- package/dist/src/formats/cys/constants.js.map +1 -1
- package/dist/src/formats/cys/exporter.d.ts +118 -0
- package/dist/src/formats/cys/exporter.d.ts.map +1 -0
- package/dist/src/formats/cys/exporter.js +1072 -0
- package/dist/src/formats/cys/exporter.js.map +1 -0
- package/dist/src/formats/cys/importer.d.ts +22 -8
- package/dist/src/formats/cys/importer.d.ts.map +1 -1
- package/dist/src/formats/cys/importer.js +510 -149
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/index.d.ts +4 -2
- package/dist/src/formats/cys/index.d.ts.map +1 -1
- package/dist/src/formats/cys/index.js +4 -2
- package/dist/src/formats/cys/index.js.map +1 -1
- package/dist/src/formats/cys/session.d.ts +46 -7
- package/dist/src/formats/cys/session.d.ts.map +1 -1
- package/dist/src/formats/cys/session.js +98 -24
- package/dist/src/formats/cys/session.js.map +1 -1
- package/dist/src/formats/cys/tables.d.ts +9 -2
- package/dist/src/formats/cys/tables.d.ts.map +1 -1
- package/dist/src/formats/cys/tables.js +29 -7
- package/dist/src/formats/cys/tables.js.map +1 -1
- package/dist/src/formats/dot/exporter.d.ts +42 -14
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +56 -29
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts +91 -29
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +190 -39
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/index.d.ts +2 -1
- package/dist/src/formats/dot/index.d.ts.map +1 -1
- package/dist/src/formats/dot/index.js +2 -1
- package/dist/src/formats/dot/index.js.map +1 -1
- package/dist/src/formats/dot/names.d.ts +44 -11
- package/dist/src/formats/dot/names.d.ts.map +1 -1
- package/dist/src/formats/dot/names.js +44 -11
- package/dist/src/formats/dot/names.js.map +1 -1
- package/dist/src/formats/dot/tokenizer.d.ts +9 -2
- package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
- package/dist/src/formats/dot/tokenizer.js +20 -5
- package/dist/src/formats/dot/tokenizer.js.map +1 -1
- package/dist/src/formats/gexf/exporter.d.ts +46 -15
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +45 -15
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +87 -23
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +471 -90
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/index.d.ts +84 -21
- package/dist/src/formats/gexf/index.d.ts.map +1 -1
- package/dist/src/formats/gexf/index.js +80 -23
- package/dist/src/formats/gexf/index.js.map +1 -1
- package/dist/src/formats/gexf/schema.d.ts +67 -15
- package/dist/src/formats/gexf/schema.d.ts.map +1 -1
- package/dist/src/formats/gexf/schema.js +59 -13
- package/dist/src/formats/gexf/schema.js.map +1 -1
- package/dist/src/formats/gml/exporter.d.ts +69 -21
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +74 -29
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts +116 -25
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +290 -61
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/index.d.ts +87 -24
- package/dist/src/formats/gml/index.d.ts.map +1 -1
- package/dist/src/formats/gml/index.js +79 -26
- package/dist/src/formats/gml/index.js.map +1 -1
- package/dist/src/formats/gml/syntax.d.ts +67 -18
- package/dist/src/formats/gml/syntax.d.ts.map +1 -1
- package/dist/src/formats/gml/syntax.js +108 -26
- package/dist/src/formats/gml/syntax.js.map +1 -1
- package/dist/src/formats/graphml/constants.d.ts +174 -44
- package/dist/src/formats/graphml/constants.d.ts.map +1 -1
- package/dist/src/formats/graphml/constants.js +165 -44
- package/dist/src/formats/graphml/constants.js.map +1 -1
- package/dist/src/formats/graphml/exporter.d.ts +17 -9
- package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
- package/dist/src/formats/graphml/exporter.js +33 -12
- package/dist/src/formats/graphml/exporter.js.map +1 -1
- package/dist/src/formats/graphml/importer.d.ts +19 -7
- package/dist/src/formats/graphml/importer.d.ts.map +1 -1
- package/dist/src/formats/graphml/importer.js +466 -39
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/graphml/index.d.ts +2 -1
- package/dist/src/formats/graphml/index.d.ts.map +1 -1
- package/dist/src/formats/graphml/index.js +2 -1
- package/dist/src/formats/graphml/index.js.map +1 -1
- package/dist/src/formats/graphml/tree.d.ts +6 -2
- package/dist/src/formats/graphml/tree.d.ts.map +1 -1
- package/dist/src/formats/graphml/tree.js +6 -2
- package/dist/src/formats/graphml/tree.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts +8 -3
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +36 -15
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/dialect.d.ts +88 -24
- package/dist/src/formats/json/dialect.d.ts.map +1 -1
- package/dist/src/formats/json/dialect.js +109 -19
- package/dist/src/formats/json/dialect.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts +134 -22
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +135 -54
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +173 -52
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +899 -220
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/index.d.ts +3 -2
- package/dist/src/formats/json/index.d.ts.map +1 -1
- package/dist/src/formats/json/index.js +3 -2
- package/dist/src/formats/json/index.js.map +1 -1
- package/dist/src/formats/json/obographs-export.d.ts +68 -0
- package/dist/src/formats/json/obographs-export.d.ts.map +1 -0
- package/dist/src/formats/json/obographs-export.js +941 -0
- package/dist/src/formats/json/obographs-export.js.map +1 -0
- package/dist/src/formats/json/obographs.d.ts +26 -0
- package/dist/src/formats/json/obographs.d.ts.map +1 -1
- package/dist/src/formats/json/obographs.js +297 -80
- package/dist/src/formats/json/obographs.js.map +1 -1
- package/dist/src/formats/neo4j/exporter.d.ts +109 -21
- package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
- package/dist/src/formats/neo4j/exporter.js +238 -85
- package/dist/src/formats/neo4j/exporter.js.map +1 -1
- package/dist/src/formats/neo4j/header.d.ts +17 -4
- package/dist/src/formats/neo4j/header.d.ts.map +1 -1
- package/dist/src/formats/neo4j/header.js +36 -4
- package/dist/src/formats/neo4j/header.js.map +1 -1
- package/dist/src/formats/neo4j/importer.d.ts +107 -27
- package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
- package/dist/src/formats/neo4j/importer.js +415 -63
- package/dist/src/formats/neo4j/importer.js.map +1 -1
- package/dist/src/formats/neo4j/index.d.ts +73 -23
- package/dist/src/formats/neo4j/index.d.ts.map +1 -1
- package/dist/src/formats/neo4j/index.js +65 -25
- package/dist/src/formats/neo4j/index.js.map +1 -1
- package/dist/src/formats/obo/exporter.d.ts +150 -0
- package/dist/src/formats/obo/exporter.d.ts.map +1 -0
- package/dist/src/formats/obo/exporter.js +1736 -0
- package/dist/src/formats/obo/exporter.js.map +1 -0
- package/dist/src/formats/obo/importer.d.ts +95 -19
- package/dist/src/formats/obo/importer.d.ts.map +1 -1
- package/dist/src/formats/obo/importer.js +475 -104
- package/dist/src/formats/obo/importer.js.map +1 -1
- package/dist/src/formats/obo/index.d.ts +6 -3
- package/dist/src/formats/obo/index.d.ts.map +1 -1
- package/dist/src/formats/obo/index.js +6 -3
- package/dist/src/formats/obo/index.js.map +1 -1
- package/dist/src/formats/obo/syntax.d.ts +108 -4
- package/dist/src/formats/obo/syntax.d.ts.map +1 -1
- package/dist/src/formats/obo/syntax.js +211 -34
- package/dist/src/formats/obo/syntax.js.map +1 -1
- package/dist/src/formats/pajek/exporter.d.ts +54 -16
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +66 -34
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts +84 -22
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +303 -83
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/index.d.ts +2 -1
- package/dist/src/formats/pajek/index.d.ts.map +1 -1
- package/dist/src/formats/pajek/index.js +2 -1
- package/dist/src/formats/pajek/index.js.map +1 -1
- package/dist/src/formats/pajek/syntax.d.ts +77 -14
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +183 -51
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/columns.d.ts +1 -0
- package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
- package/dist/src/formats/xgmml/columns.js +4 -0
- package/dist/src/formats/xgmml/columns.js.map +1 -1
- package/dist/src/formats/xgmml/constants.d.ts +186 -56
- package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
- package/dist/src/formats/xgmml/constants.js +181 -57
- package/dist/src/formats/xgmml/constants.js.map +1 -1
- package/dist/src/formats/xgmml/document.d.ts +65 -11
- package/dist/src/formats/xgmml/document.d.ts.map +1 -1
- package/dist/src/formats/xgmml/document.js +157 -28
- package/dist/src/formats/xgmml/document.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts +61 -3
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +129 -26
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/exporter.d.ts +13 -6
- package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
- package/dist/src/formats/xgmml/exporter.js +20 -21
- package/dist/src/formats/xgmml/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/importer.d.ts +33 -12
- package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
- package/dist/src/formats/xgmml/importer.js +35 -72
- package/dist/src/formats/xgmml/importer.js.map +1 -1
- package/dist/src/formats/xgmml/index.d.ts +1 -0
- package/dist/src/formats/xgmml/index.d.ts.map +1 -1
- package/dist/src/formats/xgmml/index.js +1 -0
- package/dist/src/formats/xgmml/index.js.map +1 -1
- package/dist/src/formats/xgmml/values.d.ts +8 -1
- package/dist/src/formats/xgmml/values.d.ts.map +1 -1
- package/dist/src/formats/xgmml/values.js +7 -2
- package/dist/src/formats/xgmml/values.js.map +1 -1
- package/dist/src/index.d.ts +23 -18
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +28 -16
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts +478 -92
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +807 -88
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sniff.d.ts +61 -19
- package/dist/src/sniff.d.ts.map +1 -1
- package/dist/src/sniff.js +121 -29
- package/dist/src/sniff.js.map +1 -1
- package/dist/src/types.d.ts +362 -112
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +28 -7
- package/dist/src/types.js.map +1 -1
- package/dist/xgmml.js +2 -2
- package/docs/samples/README.md +25 -0
- package/docs/samples/got-edges.csv +353 -0
- package/docs/samples/got-network.graphml +1384 -0
- package/docs/samples/got-nodes.csv +108 -0
- package/docs/samples/got.cx +930 -0
- package/docs/samples/got.cx2 +465 -0
- package/docs/samples/got.gexf +471 -0
- package/docs/samples/got.gml +2650 -0
- package/docs/samples/got.json +2546 -0
- package/docs/samples/got.net +461 -0
- package/docs/samples/movies-nodes.csv +9 -0
- package/docs/samples/movies-rels.csv +8 -0
- package/docs/samples/networks.cys +0 -0
- package/docs/samples/proteins.xgmml +9 -0
- package/docs/samples/teams.gv +24 -0
- package/docs/samples/vehicles.obo +25 -0
- package/package.json +9 -4
- package/src/children.ts +18 -6
- package/src/common/attributes.ts +29 -11
- package/src/common/cell-budget.ts +11 -3
- package/src/common/choose.ts +89 -0
- package/src/common/codes.ts +490 -66
- package/src/common/compare.ts +472 -0
- package/src/common/cx-export.ts +432 -0
- package/src/common/declared-types.ts +38 -4
- package/src/common/direction.ts +78 -51
- package/src/common/escape.ts +33 -17
- package/src/common/export.ts +284 -47
- package/src/common/format.ts +30 -1
- package/src/common/ids.ts +14 -3
- package/src/common/input.ts +1057 -134
- package/src/common/json-elements.ts +1034 -198
- package/src/common/line-format.ts +249 -0
- package/src/common/lists.ts +6 -1
- package/src/common/ontology-export.ts +461 -0
- package/src/common/ontology.ts +31 -9
- package/src/common/options.ts +110 -15
- package/src/common/plural.ts +49 -0
- package/src/common/report.ts +168 -25
- package/src/common/temporal.ts +22 -5
- package/src/common/text.ts +62 -23
- package/src/common/weights.ts +74 -4
- package/src/common/writer.ts +37 -3
- package/src/common/xml.ts +477 -88
- package/src/common/zip.ts +169 -7
- package/src/formats/csv/exporter.ts +201 -46
- package/src/formats/csv/header.ts +50 -11
- package/src/formats/csv/importer.ts +1133 -245
- package/src/formats/csv/index.ts +106 -19
- package/src/formats/csv/records.ts +396 -122
- package/src/formats/csv/values.ts +1 -0
- package/src/formats/cx/exporter.ts +1483 -0
- package/src/formats/cx/importer.ts +888 -300
- package/src/formats/cx/index.ts +4 -3
- package/src/formats/cx2/exporter.ts +61 -338
- package/src/formats/cx2/importer.ts +317 -86
- package/src/formats/cx2/index.ts +2 -1
- package/src/formats/cys/constants.ts +62 -17
- package/src/formats/cys/exporter.ts +1368 -0
- package/src/formats/cys/importer.ts +659 -157
- package/src/formats/cys/index.ts +4 -2
- package/src/formats/cys/session.ts +139 -31
- package/src/formats/cys/tables.ts +47 -9
- package/src/formats/dot/exporter.ts +83 -37
- package/src/formats/dot/importer.ts +248 -54
- package/src/formats/dot/index.ts +2 -1
- package/src/formats/dot/names.ts +44 -11
- package/src/formats/dot/tokenizer.ts +25 -6
- package/src/formats/gexf/exporter.ts +57 -18
- package/src/formats/gexf/importer.ts +636 -105
- package/src/formats/gexf/index.ts +90 -21
- package/src/formats/gexf/schema.ts +67 -15
- package/src/formats/gml/exporter.ts +90 -36
- package/src/formats/gml/importer.ts +388 -67
- package/src/formats/gml/index.ts +85 -24
- package/src/formats/gml/syntax.ts +111 -26
- package/src/formats/graphml/constants.ts +178 -44
- package/src/formats/graphml/exporter.ts +52 -18
- package/src/formats/graphml/importer.ts +640 -60
- package/src/formats/graphml/index.ts +2 -1
- package/src/formats/graphml/tree.ts +6 -2
- package/src/formats/graphml/yfiles.ts +37 -15
- package/src/formats/json/dialect.ts +128 -29
- package/src/formats/json/exporter.ts +205 -68
- package/src/formats/json/importer.ts +1163 -253
- package/src/formats/json/index.ts +3 -1
- package/src/formats/json/obographs-export.ts +1197 -0
- package/src/formats/json/obographs.ts +353 -92
- package/src/formats/neo4j/exporter.ts +320 -101
- package/src/formats/neo4j/header.ts +44 -6
- package/src/formats/neo4j/importer.ts +512 -73
- package/src/formats/neo4j/index.ts +75 -23
- package/src/formats/obo/exporter.ts +2210 -0
- package/src/formats/obo/importer.ts +622 -109
- package/src/formats/obo/index.ts +6 -3
- package/src/formats/obo/syntax.ts +232 -37
- package/src/formats/pajek/exporter.ts +89 -41
- package/src/formats/pajek/importer.ts +407 -93
- package/src/formats/pajek/index.ts +2 -1
- package/src/formats/pajek/syntax.ts +213 -52
- package/src/formats/xgmml/columns.ts +10 -0
- package/src/formats/xgmml/constants.ts +183 -56
- package/src/formats/xgmml/document.ts +212 -34
- package/src/formats/xgmml/emit.ts +175 -34
- package/src/formats/xgmml/exporter.ts +35 -27
- package/src/formats/xgmml/importer.ts +64 -86
- package/src/formats/xgmml/index.ts +1 -0
- package/src/formats/xgmml/values.ts +11 -3
- package/src/index.ts +81 -11
- package/src/registry.ts +1121 -135
- package/src/sniff.ts +163 -32
- package/src/types.ts +385 -114
- package/dist/chunks/escape-B-tkk_Cl.js.map +0 -1
- package/dist/chunks/export-Bh60Dv-n.js +0 -582
- package/dist/chunks/export-Bh60Dv-n.js.map +0 -1
- package/dist/chunks/exporter-BGrsWamJ.js.map +0 -1
- package/dist/chunks/exporter-DIeGJXAZ.js.map +0 -1
- package/dist/chunks/importer-BWY2FFc5.js.map +0 -1
- package/dist/chunks/importer-DD-xv9_Y.js +0 -1471
- package/dist/chunks/importer-DD-xv9_Y.js.map +0 -1
- package/dist/chunks/importer-DET1tg6s.js.map +0 -1
- package/dist/chunks/importer-DEcKhsmQ.js +0 -1614
- package/dist/chunks/importer-DEcKhsmQ.js.map +0 -1
- package/dist/chunks/importer-DIrbbnAf.js.map +0 -1
- package/dist/chunks/importer-D_e7e7LX.js.map +0 -1
- package/dist/chunks/importer-eUREhBGj.js.map +0 -1
- package/dist/chunks/importer-vi3bSdtw.js.map +0 -1
- package/dist/chunks/importer-zGLo8Dg_.js.map +0 -1
- package/dist/chunks/json-elements-DDS8N2Dd.js +0 -779
- package/dist/chunks/json-elements-DDS8N2Dd.js.map +0 -1
- package/dist/chunks/ontology-BnrJ4I98.js +0 -113
- package/dist/chunks/ontology-BnrJ4I98.js.map +0 -1
- package/dist/chunks/records-dbRkxwaq.js.map +0 -1
- package/dist/chunks/report-B1z4WT9e.js +0 -2372
- package/dist/chunks/report-B1z4WT9e.js.map +0 -1
- package/dist/chunks/text-Dr0Ifpag.js.map +0 -1
- package/dist/chunks/weights-Dzba96G3.js +0 -176
- package/dist/chunks/weights-Dzba96G3.js.map +0 -1
- package/dist/chunks/writer-C7flM-Ih.js.map +0 -1
package/src/common/options.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Option
|
|
2
|
+
* Option normalization for importers and exporters (design sections 8.4 and 8.5): every common
|
|
3
3
|
* option resolved to its documented default, enum values checked (E_UNSUPPORTED, the core's
|
|
4
4
|
* convention for an option outside its set), and the per-format defaults (`ids`, `defaultDirected`,
|
|
5
5
|
* `weightFrom`, `addMissingNodes`) supplied by the importer that calls resolveImportOptions().
|
|
@@ -16,9 +16,13 @@ import {
|
|
|
16
16
|
SINK_OPTION_CODE,
|
|
17
17
|
} from "./codes.js";
|
|
18
18
|
import { canonicalEncoding } from "./input.js";
|
|
19
|
+
import { plural } from "./plural.js";
|
|
19
20
|
import { type ImportReportBuilder } from "./report.js";
|
|
20
21
|
|
|
21
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* The defaults an importer supplies for the options whose default is per format.
|
|
24
|
+
* @category Plugin helpers
|
|
25
|
+
*/
|
|
22
26
|
export interface ImportFormatDefaults {
|
|
23
27
|
/** "canonical" for text-cell formats, "keep" for JSON. */
|
|
24
28
|
readonly ids: IdCoercion;
|
|
@@ -31,9 +35,9 @@ export interface ImportFormatDefaults {
|
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
/**
|
|
34
|
-
* CommonImportOptions with every field present
|
|
35
|
-
* Consumed by the per-format importers and exporters under src/formats.
|
|
38
|
+
* CommonImportOptions with every field present.
|
|
36
39
|
* @public
|
|
40
|
+
* @category Plugin helpers
|
|
37
41
|
*/
|
|
38
42
|
export interface ResolvedImportOptions {
|
|
39
43
|
/** The id coercion rule. */
|
|
@@ -70,7 +74,10 @@ export interface ResolvedImportOptions {
|
|
|
70
74
|
readonly encoding: string | null;
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* CommonExportOptions with every field present.
|
|
79
|
+
* @category Plugin helpers
|
|
80
|
+
*/
|
|
74
81
|
export interface ResolvedExportOptions {
|
|
75
82
|
/** "error" never renames a node; "mangle" rewrites and keeps the original. */
|
|
76
83
|
readonly sanitizeIds: "error" | "mangle";
|
|
@@ -89,7 +96,10 @@ const LONG_MODES: ReadonlySet<string> = new Set(["f64", "string"]);
|
|
|
89
96
|
const HYPEREDGE_POLICIES: ReadonlySet<string> = new Set(["error", "skip", "star", "clique"]);
|
|
90
97
|
const SANITIZE_MODES: ReadonlySet<string> = new Set(["error", "mangle"]);
|
|
91
98
|
|
|
92
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* The default error limit: errors tolerated before an import aborts.
|
|
101
|
+
* @category Reports and errors
|
|
102
|
+
*/
|
|
93
103
|
export const DEFAULT_ERROR_LIMIT = 100;
|
|
94
104
|
|
|
95
105
|
export { SINK_OPTION_CODE };
|
|
@@ -98,17 +108,18 @@ export { SINK_OPTION_CODE };
|
|
|
98
108
|
const SINK_OPTION_NAMES = ["addMissingNodes", "duplicateEdges", "selfLoops", "weightDtype"] as const;
|
|
99
109
|
|
|
100
110
|
/**
|
|
101
|
-
* Report every builder-policy option the caller explicitly requested that the sink does not use
|
|
102
|
-
*
|
|
111
|
+
* Report every builder-policy option the caller explicitly requested that the sink does not use,
|
|
112
|
+
* one `W_SINK_OPTION` warning per option with the option name as
|
|
103
113
|
* the element. Options left undefined are never reported: they are defaults, not requests. On the
|
|
104
114
|
* registry's builder, which is seeded from the same options, nothing is ever reported.
|
|
105
115
|
* @param sink - the sink the importer pushes into
|
|
106
116
|
* @param options - the caller's raw options, possibly undefined
|
|
107
117
|
* @param report - the report to record into
|
|
108
118
|
* @param enforcesMissingNodes - true when the importer applies `addMissingNodes: false` itself (it
|
|
109
|
-
* refuses unknown endpoints before the sink sees them), so that request is
|
|
119
|
+
* refuses unknown endpoints before the sink sees them), so that request is honored on any sink and
|
|
110
120
|
* only `addMissingNodes: true` against a refusing sink is reported
|
|
111
121
|
* @returns the number of warnings recorded
|
|
122
|
+
* @category Writing a format
|
|
112
123
|
*/
|
|
113
124
|
export function reportSinkOptions(
|
|
114
125
|
sink: GraphSink,
|
|
@@ -156,15 +167,28 @@ const IGNORABLE_OPTION_NAMES = [
|
|
|
156
167
|
"hyperedges",
|
|
157
168
|
] as const;
|
|
158
169
|
|
|
170
|
+
/** The defaults that are the same in every format (the others, such as `defaultDirected`, differ by format). */
|
|
171
|
+
const FIXED_DEFAULTS: Readonly<Partial<Record<(typeof IGNORABLE_OPTION_NAMES)[number], unknown>>> = {
|
|
172
|
+
nodeIdFrom: "id",
|
|
173
|
+
duplicateEdges: "keep",
|
|
174
|
+
selfLoops: "keep",
|
|
175
|
+
onMixedDirection: "expand",
|
|
176
|
+
weightDtype: "f64",
|
|
177
|
+
long: "f64",
|
|
178
|
+
restoreMangledIds: true,
|
|
179
|
+
hyperedges: "skip",
|
|
180
|
+
};
|
|
181
|
+
|
|
159
182
|
/**
|
|
160
183
|
* Report every common option the caller set to a non-default value that the format has no use
|
|
161
|
-
* for
|
|
184
|
+
* for: one
|
|
162
185
|
* `W_OPTION_IGNORED` warning (category `unsupported`) per option, the option name as the element.
|
|
163
186
|
* The builder-policy options are reportSinkOptions()'s and are skipped here.
|
|
164
187
|
* @param options - the caller's raw options, possibly undefined
|
|
165
188
|
* @param report - the report to record into
|
|
166
189
|
* @param used - the common option names the importer reads
|
|
167
190
|
* @returns the number of warnings recorded
|
|
191
|
+
* @category Writing a format
|
|
168
192
|
*/
|
|
169
193
|
export function reportUnusedOptions(
|
|
170
194
|
options: CommonImportOptions | undefined,
|
|
@@ -180,7 +204,8 @@ export function reportUnusedOptions(
|
|
|
180
204
|
continue;
|
|
181
205
|
}
|
|
182
206
|
const value: unknown = options[name];
|
|
183
|
-
if (value === undefined) {
|
|
207
|
+
if (value === undefined || value === FIXED_DEFAULTS[name]) {
|
|
208
|
+
// an option spelled out at its default changes nothing, whether or not the format reads it
|
|
184
209
|
continue;
|
|
185
210
|
}
|
|
186
211
|
report.warning(
|
|
@@ -194,6 +219,29 @@ export function reportUnusedOptions(
|
|
|
194
219
|
return recorded;
|
|
195
220
|
}
|
|
196
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Whether the caller chose a graph with `graphIndex` or `graphName`. An importer warns
|
|
224
|
+
* W_MULTIPLE_GRAPHS about the graphs it skipped only when it read the first by default.
|
|
225
|
+
* @param options - the caller's graphIndex / graphName
|
|
226
|
+
* @returns true when either option is set
|
|
227
|
+
* @category Writing a format
|
|
228
|
+
*/
|
|
229
|
+
export function graphChosen(options: GraphChoiceOptions | undefined): boolean {
|
|
230
|
+
return options?.graphIndex !== undefined || options?.graphName !== undefined;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* The graphs of an input as an E_GRAPH_NOT_FOUND message lists them: their indexes and names, so the
|
|
235
|
+
* caller can choose without a second call.
|
|
236
|
+
* @param names - each graph's name, null for an unnamed graph
|
|
237
|
+
* @returns the text to append, starting with "; "
|
|
238
|
+
*/
|
|
239
|
+
function graphNamesText(names: readonly (string | null)[]): string {
|
|
240
|
+
const shown = names.slice(0, 10).map((n, i) => `${i} ${n === null ? "(unnamed)" : JSON.stringify(n)}`);
|
|
241
|
+
const more = names.length > shown.length ? `, and ${names.length - shown.length} more` : "";
|
|
242
|
+
return `; the file holds ${shown.join(", ")}${more}`;
|
|
243
|
+
}
|
|
244
|
+
|
|
197
245
|
/**
|
|
198
246
|
* The graph an importer reads from an input that holds several: the one `graphIndex` or
|
|
199
247
|
* `graphName` names, else the first. A choice that names no graph is E_GRAPH_NOT_FOUND, a name two
|
|
@@ -203,6 +251,7 @@ export function reportUnusedOptions(
|
|
|
203
251
|
* @param options - the caller's graphIndex / graphName
|
|
204
252
|
* @param report - the report a failure is recorded in
|
|
205
253
|
* @returns the index of the graph to read; E_UNSUPPORTED for an option of the wrong type, or both
|
|
254
|
+
* @category Writing a format
|
|
206
255
|
*/
|
|
207
256
|
export function chooseGraph(
|
|
208
257
|
names: readonly (string | null)[],
|
|
@@ -250,7 +299,7 @@ export function chooseGraph(
|
|
|
250
299
|
if (matches.length === 0) {
|
|
251
300
|
return report.fail(
|
|
252
301
|
GRAPH_NOT_FOUND_CODE,
|
|
253
|
-
`graphName ${JSON.stringify(graphName)} names none of the ${names.length} graph(
|
|
302
|
+
`graphName ${JSON.stringify(graphName)} names none of the ${names.length} graph${plural(names.length)}${graphNamesText(names)}`,
|
|
254
303
|
{ element: graphName },
|
|
255
304
|
{ names: [...names] },
|
|
256
305
|
);
|
|
@@ -259,17 +308,21 @@ export function chooseGraph(
|
|
|
259
308
|
}
|
|
260
309
|
const index = graphIndex ?? 0;
|
|
261
310
|
if (index >= names.length) {
|
|
262
|
-
return report.fail(
|
|
311
|
+
return report.fail(
|
|
312
|
+
GRAPH_NOT_FOUND_CODE,
|
|
313
|
+
`graphIndex ${index} is beyond the ${names.length} graph${plural(names.length)}${graphNamesText(names)}`,
|
|
314
|
+
);
|
|
263
315
|
}
|
|
264
316
|
return index;
|
|
265
317
|
}
|
|
266
318
|
|
|
267
319
|
/**
|
|
268
|
-
* Apply the
|
|
320
|
+
* Apply the documented defaults to an importer's common options and check every enum
|
|
269
321
|
* value. Format-specific options in the same object are ignored here.
|
|
270
322
|
* @param options - the caller's options, possibly undefined
|
|
271
323
|
* @param defaults - the importer's per-format defaults
|
|
272
324
|
* @returns the resolved options; E_UNSUPPORTED for a value outside its set
|
|
325
|
+
* @category Writing a format
|
|
273
326
|
*/
|
|
274
327
|
export function resolveImportOptions(
|
|
275
328
|
options: CommonImportOptions | undefined,
|
|
@@ -297,9 +350,10 @@ export function resolveImportOptions(
|
|
|
297
350
|
}
|
|
298
351
|
|
|
299
352
|
/**
|
|
300
|
-
* Apply the
|
|
353
|
+
* Apply the documented defaults to an exporter's common options and check the enum values.
|
|
301
354
|
* @param options - the caller's options, possibly undefined
|
|
302
355
|
* @returns the resolved options; E_UNSUPPORTED for a value outside its set
|
|
356
|
+
* @category Writing a format
|
|
303
357
|
*/
|
|
304
358
|
export function resolveExportOptions(options: CommonExportOptions | undefined): ResolvedExportOptions {
|
|
305
359
|
const o: CommonExportOptions = options ?? {};
|
|
@@ -450,10 +504,51 @@ function encodingOption(value: unknown): string | null {
|
|
|
450
504
|
return canonical;
|
|
451
505
|
}
|
|
452
506
|
|
|
507
|
+
/**
|
|
508
|
+
* The options to pass to another importer that you hand text you already decoded with readText():
|
|
509
|
+
* the caller's options without `encoding` and `onProgress`, which that text no longer needs. Without
|
|
510
|
+
* this, the other importer would warn that `encoding` has no effect on text, and report progress a
|
|
511
|
+
* second time.
|
|
512
|
+
* @example
|
|
513
|
+
* ```ts
|
|
514
|
+
* const text = await readText(input, report, opts);
|
|
515
|
+
* report.include(await csvImporter.import(text, sink, forDecodedText(options)));
|
|
516
|
+
* ```
|
|
517
|
+
* @param options - the caller's import options
|
|
518
|
+
* @returns a copy without `encoding` and `onProgress`
|
|
519
|
+
* @category Writing a format
|
|
520
|
+
*/
|
|
521
|
+
export function forDecodedText<O extends CommonImportOptions>(options: O | undefined): O {
|
|
522
|
+
return { ...options, encoding: undefined, onProgress: undefined } as O;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* The dialect names of the built-in formats with a `dialect` save option. One options object shared between formats
|
|
527
|
+
* can hold one format's dialect, and the other formats ignore it, as they ignore any option they do not have.
|
|
528
|
+
*/
|
|
529
|
+
export const FORMAT_DIALECTS: Readonly<Record<string, readonly string[]>> = Object.freeze({
|
|
530
|
+
csv: Object.freeze(["gephi", "generic"]),
|
|
531
|
+
json: Object.freeze(["node-link", "d3", "jgf", "cytoscape", "graphology", "vis", "obographs"]),
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Whether a `dialect` value names another format's dialect, which this format ignores rather than refuses.
|
|
536
|
+
* @param format - this format
|
|
537
|
+
* @param value - the caller's `dialect` option
|
|
538
|
+
* @returns true for another built-in format's dialect name
|
|
539
|
+
*/
|
|
540
|
+
export function otherFormatDialect(format: string, value: unknown): boolean {
|
|
541
|
+
return (
|
|
542
|
+
typeof value === "string" &&
|
|
543
|
+
Object.entries(FORMAT_DIALECTS).some(([f, names]) => f !== format && names.includes(value))
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
|
|
453
547
|
/**
|
|
454
548
|
* A short description of an option value for an error message.
|
|
455
549
|
* @param value - the value
|
|
456
550
|
* @returns the JSON text of a primitive, or the type name otherwise
|
|
551
|
+
* @category Plugin helpers
|
|
457
552
|
*/
|
|
458
553
|
export function describe(value: unknown): string {
|
|
459
554
|
switch (typeof value) {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Count agreement for messages, so a report says "1 node is" and "3 nodes are", never "1 node(s) are".
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The plural ending of a regular noun after a count.
|
|
7
|
+
* @param n - the count
|
|
8
|
+
* @returns "" for 1, "s" otherwise
|
|
9
|
+
*/
|
|
10
|
+
export function plural(n: number): string {
|
|
11
|
+
return n === 1 ? "" : "s";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The form of a verb that agrees with a count.
|
|
16
|
+
* @param n - the count
|
|
17
|
+
* @param one - the form for 1 ("is", "was", "holds")
|
|
18
|
+
* @param many - the form for any other count ("are", "were", "hold")
|
|
19
|
+
* @returns `one` or `many`
|
|
20
|
+
*/
|
|
21
|
+
export function agree(n: number, one: string, many: string): string {
|
|
22
|
+
return n === 1 ? one : many;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* A count of nodes and edges, leaving out a zero: "2 nodes and 1 edge", "1 edge".
|
|
27
|
+
* @param nodes - the node count
|
|
28
|
+
* @param edges - the edge count
|
|
29
|
+
* @returns the text
|
|
30
|
+
*/
|
|
31
|
+
export function elementCount(nodes: number, edges: number): string {
|
|
32
|
+
const parts = [];
|
|
33
|
+
if (nodes > 0 || edges === 0) {
|
|
34
|
+
parts.push(`${nodes} node${plural(nodes)}`);
|
|
35
|
+
}
|
|
36
|
+
if (edges > 0) {
|
|
37
|
+
parts.push(`${edges} edge${plural(edges)}`);
|
|
38
|
+
}
|
|
39
|
+
return parts.join(" and ");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A word with its indefinite article, chosen by its first letter: "an integer", "a double".
|
|
44
|
+
* @param word - the word
|
|
45
|
+
* @returns "a word" or "an word"
|
|
46
|
+
*/
|
|
47
|
+
export function withArticle(word: string): string {
|
|
48
|
+
return `${/^[aeiou]/i.test(word) ? "an" : "a"} ${word}`;
|
|
49
|
+
}
|
package/src/common/report.ts
CHANGED
|
@@ -13,11 +13,20 @@
|
|
|
13
13
|
import { GraphFormatError, type GraphFormatErrorCode } from "@graphty/graph-format";
|
|
14
14
|
|
|
15
15
|
import { ImportError, type ImportIssue, type ImportReport, type IssueCategory, type LossNote } from "../types.js";
|
|
16
|
+
import { ISSUES_SUPPRESSED_CODE } from "./codes.js";
|
|
17
|
+
import { agree, plural } from "./plural.js";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The most warnings of one code a report keeps; later ones are counted in one W_ISSUES_SUPPRESSED
|
|
21
|
+
* warning, so a per-row warning on a large file cannot grow the report without bound.
|
|
22
|
+
* @category Issue and loss codes
|
|
23
|
+
*/
|
|
24
|
+
export const MAX_WARNINGS_PER_CODE = 1000;
|
|
16
25
|
|
|
17
26
|
/**
|
|
18
27
|
* Where an issue was found: the 1-based line and the element (id or attribute name) when known.
|
|
19
|
-
* Consumed by the per-format importers and exporters under src/formats.
|
|
20
28
|
* @public
|
|
29
|
+
* @category Writing a format
|
|
21
30
|
*/
|
|
22
31
|
export interface IssueLocation {
|
|
23
32
|
/** The 1-based source line, when known. */
|
|
@@ -28,8 +37,8 @@ export interface IssueLocation {
|
|
|
28
37
|
|
|
29
38
|
/**
|
|
30
39
|
* The mutable element counters of a report in progress; importers increment them directly in hot loops.
|
|
31
|
-
* Consumed by the per-format importers and exporters under src/formats.
|
|
32
40
|
* @public
|
|
41
|
+
* @category Plugin helpers
|
|
33
42
|
*/
|
|
34
43
|
export interface MutableCounts {
|
|
35
44
|
/** Nodes pushed. */
|
|
@@ -40,7 +49,7 @@ export interface MutableCounts {
|
|
|
40
49
|
skippedNodes: number;
|
|
41
50
|
/** Edges skipped after an error. */
|
|
42
51
|
skippedEdges: number;
|
|
43
|
-
/** Source edges expanded into two logical edges
|
|
52
|
+
/** Source edges expanded into two logical edges. */
|
|
44
53
|
expandedMixed: number;
|
|
45
54
|
}
|
|
46
55
|
|
|
@@ -60,18 +69,30 @@ const CATEGORY_BY_CODE: Readonly<Partial<Record<GraphFormatErrorCode, IssueCateg
|
|
|
60
69
|
};
|
|
61
70
|
|
|
62
71
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* input) propagates out of import() untouched, so no importer records this code any more; the
|
|
66
|
-
* constant stays for consumers that switch on the codes of earlier reports.
|
|
72
|
+
* No longer recorded; kept so code that switches on older reports still compiles.
|
|
73
|
+
* @category Issue and loss codes
|
|
67
74
|
*/
|
|
68
75
|
export const PARSE_ERROR_CODE = "E_PARSE";
|
|
69
76
|
|
|
77
|
+
/**
|
|
78
|
+
* An issue message as the ImportError shows it: prefixed with its line when the issue has one and the
|
|
79
|
+
* message does not already name it.
|
|
80
|
+
* @param message - the issue message
|
|
81
|
+
* @param where - the issue location
|
|
82
|
+
* @returns the message for the error
|
|
83
|
+
*/
|
|
84
|
+
function withLine(message: string, where: IssueLocation | undefined): string {
|
|
85
|
+
const line = where?.line;
|
|
86
|
+
return line === undefined || line === null || message.includes(`line ${line}`)
|
|
87
|
+
? message
|
|
88
|
+
: `line ${line}: ${message}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
70
91
|
/**
|
|
71
92
|
* Accumulates an ImportReport while an importer runs. Errors count toward the error limit; the
|
|
72
93
|
* error that takes the count beyond the limit is still recorded, `truncated` is set, and an
|
|
73
|
-
* ImportError carrying the report so far is thrown
|
|
74
|
-
*
|
|
94
|
+
* ImportError carrying the report so far is thrown. Warnings never abort.
|
|
95
|
+
* @category Writing a format
|
|
75
96
|
*/
|
|
76
97
|
export class ImportReportBuilder {
|
|
77
98
|
/** The importer's format name. */
|
|
@@ -89,6 +110,9 @@ export class ImportReportBuilder {
|
|
|
89
110
|
|
|
90
111
|
private readonly onceCodes = new Set<string>();
|
|
91
112
|
|
|
113
|
+
/** Warnings recorded per code, kept or not. */
|
|
114
|
+
private readonly warningsByCode = new Map<string, number>();
|
|
115
|
+
|
|
92
116
|
private errors = 0;
|
|
93
117
|
|
|
94
118
|
private warnings = 0;
|
|
@@ -163,7 +187,7 @@ export class ImportReportBuilder {
|
|
|
163
187
|
this.errors++;
|
|
164
188
|
if (this.errors > this.errorLimit) {
|
|
165
189
|
this.truncatedFlag = true;
|
|
166
|
-
throw this.abort(`error limit of ${this.errorLimit} exceeded: ${message}`, {
|
|
190
|
+
throw this.abort(`error limit of ${this.errorLimit} exceeded: ${withLine(message, where)}`, {
|
|
167
191
|
code,
|
|
168
192
|
limit: this.errorLimit,
|
|
169
193
|
});
|
|
@@ -172,7 +196,9 @@ export class ImportReportBuilder {
|
|
|
172
196
|
}
|
|
173
197
|
|
|
174
198
|
/**
|
|
175
|
-
* Record a warning; warnings never count toward the limit.
|
|
199
|
+
* Record a warning; warnings never count toward the limit. Beyond MAX_WARNINGS_PER_CODE
|
|
200
|
+
* warnings of one code the warning is counted, not kept: finish() adds one W_ISSUES_SUPPRESSED
|
|
201
|
+
* warning per such code with the number dropped.
|
|
176
202
|
* @param category - the issue category
|
|
177
203
|
* @param code - a stable code such as "W_WIDENED"
|
|
178
204
|
* @param message - a plain-ASCII message
|
|
@@ -181,8 +207,12 @@ export class ImportReportBuilder {
|
|
|
181
207
|
*/
|
|
182
208
|
warning(category: IssueCategory, code: string, message: string, where?: IssueLocation): ImportIssue {
|
|
183
209
|
const issue = makeIssue(category, "warning", code, message, where);
|
|
184
|
-
this.
|
|
185
|
-
this.
|
|
210
|
+
const seen = (this.warningsByCode.get(code) ?? 0) + 1;
|
|
211
|
+
this.warningsByCode.set(code, seen);
|
|
212
|
+
if (seen <= MAX_WARNINGS_PER_CODE) {
|
|
213
|
+
this.issueList.push(issue);
|
|
214
|
+
this.warnings++;
|
|
215
|
+
}
|
|
186
216
|
return issue;
|
|
187
217
|
}
|
|
188
218
|
|
|
@@ -226,7 +256,7 @@ export class ImportReportBuilder {
|
|
|
226
256
|
}
|
|
227
257
|
|
|
228
258
|
/**
|
|
229
|
-
* The per-element catch
|
|
259
|
+
* The per-element catch: record a thrown GraphFormatError as an error
|
|
230
260
|
* issue with its code and the category the code implies. Anything else is re-thrown unchanged:
|
|
231
261
|
* an ImportError (the import already aborted), an abort reason, and any other thrown value (a
|
|
232
262
|
* TypeError or RangeError is a programming error in the importer or the sink, never a defect of
|
|
@@ -238,11 +268,38 @@ export class ImportReportBuilder {
|
|
|
238
268
|
recordError(err: unknown, where?: IssueLocation): ImportIssue {
|
|
239
269
|
if (err instanceof GraphFormatError && !(err instanceof ImportError)) {
|
|
240
270
|
const category = CATEGORY_BY_CODE[err.code] ?? "validation-error";
|
|
271
|
+
if (err.code === "E_TOO_LARGE") {
|
|
272
|
+
// the sink is full: every later element would fail the same way, so the import stops
|
|
273
|
+
return this.failWith(category, err.code, err.message, where);
|
|
274
|
+
}
|
|
241
275
|
return this.error(category, err.code, err.message, where);
|
|
242
276
|
}
|
|
243
277
|
throw err;
|
|
244
278
|
}
|
|
245
279
|
|
|
280
|
+
/**
|
|
281
|
+
* A builder that starts from everything this one recorded so far: issues, counts, loss notes,
|
|
282
|
+
* the warnOnce keys, the error and warning counts and the truncation flag. For an importer that
|
|
283
|
+
* reads its input once and emits several graphs, each with its own report.
|
|
284
|
+
* @returns the copy; later records to either builder do not reach the other
|
|
285
|
+
*/
|
|
286
|
+
fork(): ImportReportBuilder {
|
|
287
|
+
const copy = new ImportReportBuilder(this.format, this.errorLimit);
|
|
288
|
+
Object.assign(copy.counts, this.counts);
|
|
289
|
+
copy.issueList.push(...this.issueList);
|
|
290
|
+
copy.lossList.push(...this.lossList);
|
|
291
|
+
for (const key of this.onceCodes) {
|
|
292
|
+
copy.onceCodes.add(key);
|
|
293
|
+
}
|
|
294
|
+
for (const [code, count] of this.warningsByCode) {
|
|
295
|
+
copy.warningsByCode.set(code, count);
|
|
296
|
+
}
|
|
297
|
+
copy.errors = this.errors;
|
|
298
|
+
copy.warnings = this.warnings;
|
|
299
|
+
copy.truncatedFlag = this.truncatedFlag;
|
|
300
|
+
return copy;
|
|
301
|
+
}
|
|
302
|
+
|
|
246
303
|
/**
|
|
247
304
|
* Build the ImportError that aborts the import, carrying the report so far. The caller throws
|
|
248
305
|
* it; this method only constructs it so it can be used in expression position.
|
|
@@ -263,13 +320,65 @@ export class ImportReportBuilder {
|
|
|
263
320
|
* @param details - optional machine-readable context for the ImportError
|
|
264
321
|
*/
|
|
265
322
|
fail(code: string, message: string, where?: IssueLocation, details?: Readonly<Record<string, unknown>>): never {
|
|
266
|
-
|
|
267
|
-
|
|
323
|
+
this.failWith("parse-error", code, message, where, details);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Record a fatal error of any category and abort, as fail() does for a parse error: a size
|
|
328
|
+
* limit (E_TOO_LARGE, category "unsupported") stops an import without being a defect of the
|
|
329
|
+
* syntax. A fatal error is not the error limit: `truncated` stays as it was.
|
|
330
|
+
* @param category - the issue category
|
|
331
|
+
* @param code - a stable code
|
|
332
|
+
* @param message - a plain-ASCII message
|
|
333
|
+
* @param where - the line and element, when known
|
|
334
|
+
* @param details - optional machine-readable context for the ImportError
|
|
335
|
+
*/
|
|
336
|
+
failWith(
|
|
337
|
+
category: IssueCategory,
|
|
338
|
+
code: string,
|
|
339
|
+
message: string,
|
|
340
|
+
where?: IssueLocation,
|
|
341
|
+
details?: Readonly<Record<string, unknown>>,
|
|
342
|
+
): never {
|
|
343
|
+
this.issueList.push(makeIssue(category, "error", code, message, where));
|
|
268
344
|
this.errors++;
|
|
269
|
-
|
|
270
|
-
|
|
345
|
+
throw this.abort(withLine(message, where), { code, ...details });
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Add a finished report to this one: its issues after the ones recorded so far, its counts, its
|
|
350
|
+
* loss notes and its truncated flag. Use it when an importer hands part of the work to another
|
|
351
|
+
* importer (for example, a wrapper around the CSV importer) and returns one report for both. The issues
|
|
352
|
+
* keep their codes; errors added this way do not count toward this report's error limit, since
|
|
353
|
+
* the other importer applied its own.
|
|
354
|
+
* @param report - the report the other importer returned
|
|
355
|
+
* @returns this builder
|
|
356
|
+
* @example
|
|
357
|
+
* ```ts
|
|
358
|
+
* const report = new ImportReportBuilder("netscope", opts.errorLimit);
|
|
359
|
+
* const text = await readText(input, report, opts);
|
|
360
|
+
* report.include(await csvImporter.import(text, sink, options));
|
|
361
|
+
* return report.finish();
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
include(report: ImportReport): this {
|
|
365
|
+
for (const issue of report.issues) {
|
|
366
|
+
this.issueList.push(issue);
|
|
367
|
+
if (issue.severity === "error") {
|
|
368
|
+
this.errors++;
|
|
369
|
+
} else {
|
|
370
|
+
this.warnings++;
|
|
371
|
+
}
|
|
271
372
|
}
|
|
272
|
-
|
|
373
|
+
const { counts } = report;
|
|
374
|
+
this.counts.nodes += counts.nodes;
|
|
375
|
+
this.counts.edges += counts.edges;
|
|
376
|
+
this.counts.skippedNodes += counts.skippedNodes;
|
|
377
|
+
this.counts.skippedEdges += counts.skippedEdges;
|
|
378
|
+
this.counts.expandedMixed += counts.expandedMixed;
|
|
379
|
+
this.lossList.push(...report.lossy);
|
|
380
|
+
this.truncatedFlag ||= report.truncated;
|
|
381
|
+
return this;
|
|
273
382
|
}
|
|
274
383
|
|
|
275
384
|
/**
|
|
@@ -279,12 +388,27 @@ export class ImportReportBuilder {
|
|
|
279
388
|
*/
|
|
280
389
|
finish(): ImportReport {
|
|
281
390
|
const { nodes, edges, skippedNodes, skippedEdges, expandedMixed } = this.counts;
|
|
391
|
+
const suppressed: ImportIssue[] = [];
|
|
392
|
+
for (const [code, seen] of this.warningsByCode) {
|
|
393
|
+
if (seen > MAX_WARNINGS_PER_CODE) {
|
|
394
|
+
const more = seen - MAX_WARNINGS_PER_CODE;
|
|
395
|
+
suppressed.push(
|
|
396
|
+
makeIssue(
|
|
397
|
+
"unsupported",
|
|
398
|
+
"warning",
|
|
399
|
+
ISSUES_SUPPRESSED_CODE,
|
|
400
|
+
`${more} more ${code} warning${plural(more)} ${agree(more, "was", "were")} not kept (the report keeps the first ${MAX_WARNINGS_PER_CODE})`,
|
|
401
|
+
{ element: code },
|
|
402
|
+
),
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
282
406
|
return Object.freeze({
|
|
283
407
|
format: this.format,
|
|
284
408
|
counts: Object.freeze({ nodes, edges, skippedNodes, skippedEdges, expandedMixed }),
|
|
285
|
-
issues: Object.freeze([...this.issueList]),
|
|
409
|
+
issues: Object.freeze([...this.issueList, ...suppressed]),
|
|
286
410
|
errorCount: this.errors,
|
|
287
|
-
warningCount: this.warnings,
|
|
411
|
+
warningCount: this.warnings + suppressed.length,
|
|
288
412
|
truncated: this.truncatedFlag,
|
|
289
413
|
lossy: Object.freeze([...this.lossList]),
|
|
290
414
|
durationMs: now() - this.startedAt,
|
|
@@ -319,19 +443,38 @@ function makeIssue(
|
|
|
319
443
|
}
|
|
320
444
|
|
|
321
445
|
/**
|
|
322
|
-
* Whether a thrown value
|
|
323
|
-
*
|
|
446
|
+
* Whether a thrown value means the load was cancelled rather than failed: the DOMException or Error
|
|
447
|
+
* named "AbortError" that an aborted signal throws, or the "TimeoutError" of AbortSignal.timeout().
|
|
448
|
+
* Use it in a `catch` block to say nothing to the user when they cancelled. A custom reason passed
|
|
449
|
+
* to `abort(reason)` is not recognized: compare it with `signal.reason`. A format plugin uses it to
|
|
450
|
+
* let a cancellation through untouched.
|
|
324
451
|
* @param err - the thrown value
|
|
325
|
-
* @returns true for an AbortError
|
|
452
|
+
* @returns true for an AbortError or a TimeoutError
|
|
453
|
+
* @example
|
|
454
|
+
* ```ts
|
|
455
|
+
* try {
|
|
456
|
+
* await loadFromUrl(url, { signal });
|
|
457
|
+
* } catch (err) {
|
|
458
|
+
* if (!isAbortError(err)) {
|
|
459
|
+
* showError(err);
|
|
460
|
+
* }
|
|
461
|
+
* }
|
|
462
|
+
* ```
|
|
463
|
+
* @category Reports and errors
|
|
326
464
|
*/
|
|
327
465
|
export function isAbortError(err: unknown): boolean {
|
|
328
|
-
|
|
466
|
+
if (typeof err !== "object" || err === null) {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
const { name } = err as { name?: unknown };
|
|
470
|
+
return name === "AbortError" || name === "TimeoutError";
|
|
329
471
|
}
|
|
330
472
|
|
|
331
473
|
/**
|
|
332
474
|
* The message of a thrown value: an Error's message, a string as is, anything else described by type.
|
|
333
475
|
* @param err - the thrown value
|
|
334
476
|
* @returns a plain message
|
|
477
|
+
* @category Plugin helpers
|
|
335
478
|
*/
|
|
336
479
|
export function messageOf(err: unknown): string {
|
|
337
480
|
if (err instanceof Error) {
|