@graphty/graph-io 0.3.17 → 0.3.19
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/LICENSE +1 -1
- package/README.md +64 -3
- package/dist/chunks/{escape-scjHxjpr.js → escape-CWExcecC.js} +3 -2
- package/dist/chunks/{escape-scjHxjpr.js.map → escape-CWExcecC.js.map} +1 -1
- package/dist/chunks/exporter-CbMZyVt-.js +735 -0
- package/dist/chunks/exporter-CbMZyVt-.js.map +1 -0
- package/dist/chunks/importer-BAP4PrxR.js +2194 -0
- package/dist/chunks/importer-BAP4PrxR.js.map +1 -0
- package/dist/chunks/{importer-Xg07gk7p.js → importer-BNFuV1-K.js} +5 -3
- package/dist/chunks/{importer-Xg07gk7p.js.map → importer-BNFuV1-K.js.map} +1 -1
- package/dist/chunks/{importer-BmOl9gLW.js → importer-BVGtU1NA.js} +5 -3
- package/dist/chunks/{importer-BmOl9gLW.js.map → importer-BVGtU1NA.js.map} +1 -1
- package/dist/chunks/{importer-ruMWWvVs.js → importer-BW-Ft2ps.js} +5 -3
- package/dist/chunks/{importer-ruMWWvVs.js.map → importer-BW-Ft2ps.js.map} +1 -1
- package/dist/chunks/{importer-B6rKRxzv.js → importer-Bm1_5vPS.js} +781 -104
- package/dist/chunks/importer-Bm1_5vPS.js.map +1 -0
- package/dist/chunks/importer-ByPGO-09.js +1614 -0
- package/dist/chunks/importer-ByPGO-09.js.map +1 -0
- package/dist/chunks/importer-DOepkgnG.js +1713 -0
- package/dist/chunks/importer-DOepkgnG.js.map +1 -0
- package/dist/chunks/json-elements-CZY1wiZh.js +779 -0
- package/dist/chunks/json-elements-CZY1wiZh.js.map +1 -0
- package/dist/chunks/ontology-BnrJ4I98.js +113 -0
- package/dist/chunks/ontology-BnrJ4I98.js.map +1 -0
- package/dist/chunks/{records-DSpbTE5s.js → records-BzNicMsf.js} +2 -2
- package/dist/chunks/{records-DSpbTE5s.js.map → records-BzNicMsf.js.map} +1 -1
- package/dist/chunks/{writer-DHHfHn11.js → report-BcWboivV.js} +106 -928
- package/dist/chunks/report-BcWboivV.js.map +1 -0
- package/dist/chunks/weights-CwISIpCP.js +176 -0
- package/dist/chunks/weights-CwISIpCP.js.map +1 -0
- package/dist/chunks/writer-DQiKgQJc.js +656 -0
- package/dist/chunks/writer-DQiKgQJc.js.map +1 -0
- package/dist/csv.js +5 -3
- package/dist/csv.js.map +1 -1
- package/dist/cx.d.ts +1 -0
- package/dist/cx.js +6 -0
- package/dist/cx.js.map +1 -0
- package/dist/cx2.d.ts +1 -0
- package/dist/cx2.js +10 -0
- package/dist/cx2.js.map +1 -0
- package/dist/dot.js +1 -1
- package/dist/gexf.js +15 -3
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +5 -3
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +158 -383
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +1 -1
- package/dist/json.js +1 -1
- package/dist/neo4j.js +5 -3
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.d.ts +1 -0
- package/dist/obo.js +6 -0
- package/dist/obo.js.map +1 -0
- package/dist/pajek.js +1 -1
- package/dist/src/common/json-elements.d.ts +286 -0
- package/dist/src/common/json-elements.d.ts.map +1 -0
- package/dist/src/common/json-elements.js +926 -0
- package/dist/src/common/json-elements.js.map +1 -0
- package/dist/src/common/ontology.d.ts +59 -0
- package/dist/src/common/ontology.d.ts.map +1 -0
- package/dist/src/common/ontology.js +147 -0
- package/dist/src/common/ontology.js.map +1 -0
- package/dist/src/formats/cx/importer.d.ts +133 -0
- package/dist/src/formats/cx/importer.d.ts.map +1 -0
- package/dist/src/formats/cx/importer.js +2220 -0
- package/dist/src/formats/cx/importer.js.map +1 -0
- package/dist/src/formats/cx/index.d.ts +7 -0
- package/dist/src/formats/cx/index.d.ts.map +1 -0
- package/dist/src/formats/cx/index.js +7 -0
- package/dist/src/formats/cx/index.js.map +1 -0
- package/dist/src/formats/cx2/exporter.d.ts +59 -0
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -0
- package/dist/src/formats/cx2/exporter.js +864 -0
- package/dist/src/formats/cx2/exporter.js.map +1 -0
- package/dist/src/formats/cx2/importer.d.ts +169 -0
- package/dist/src/formats/cx2/importer.d.ts.map +1 -0
- package/dist/src/formats/cx2/importer.js +1652 -0
- package/dist/src/formats/cx2/importer.js.map +1 -0
- package/dist/src/formats/cx2/index.d.ts +7 -0
- package/dist/src/formats/cx2/index.d.ts.map +1 -0
- package/dist/src/formats/cx2/index.js +7 -0
- package/dist/src/formats/cx2/index.js.map +1 -0
- package/dist/src/formats/gexf/exporter.d.ts +2 -0
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +6 -0
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +2 -4
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +2 -4
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/index.d.ts +1 -1
- package/dist/src/formats/gexf/index.js +2 -2
- package/dist/src/formats/gexf/index.js.map +1 -1
- package/dist/src/formats/gml/exporter.js +1 -1
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/json/dialect.d.ts +8 -6
- package/dist/src/formats/json/dialect.d.ts.map +1 -1
- package/dist/src/formats/json/dialect.js +26 -3
- package/dist/src/formats/json/dialect.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +324 -7
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +159 -126
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/obographs.d.ts +21 -0
- package/dist/src/formats/json/obographs.d.ts.map +1 -0
- package/dist/src/formats/json/obographs.js +476 -0
- package/dist/src/formats/json/obographs.js.map +1 -0
- package/dist/src/formats/obo/importer.d.ts +90 -0
- package/dist/src/formats/obo/importer.d.ts.map +1 -0
- package/dist/src/formats/obo/importer.js +1248 -0
- package/dist/src/formats/obo/importer.js.map +1 -0
- package/dist/src/formats/obo/index.d.ts +7 -0
- package/dist/src/formats/obo/index.d.ts.map +1 -0
- package/dist/src/formats/obo/index.js +7 -0
- package/dist/src/formats/obo/index.js.map +1 -0
- package/dist/src/formats/obo/syntax.d.ts +121 -0
- package/dist/src/formats/obo/syntax.d.ts.map +1 -0
- package/dist/src/formats/obo/syntax.js +424 -0
- package/dist/src/formats/obo/syntax.js.map +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +8 -1
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sniff.d.ts +1 -1
- package/dist/src/sniff.d.ts.map +1 -1
- package/dist/src/sniff.js +25 -3
- package/dist/src/sniff.js.map +1 -1
- package/package.json +16 -1
- package/src/common/json-elements.ts +1147 -0
- package/src/common/ontology.ts +169 -0
- package/src/formats/cx/importer.ts +2733 -0
- package/src/formats/cx/index.ts +7 -0
- package/src/formats/cx2/exporter.ts +1036 -0
- package/src/formats/cx2/importer.ts +2187 -0
- package/src/formats/cx2/index.ts +7 -0
- package/src/formats/gexf/exporter.ts +11 -0
- package/src/formats/gexf/importer.ts +2 -2
- package/src/formats/gexf/index.ts +1 -1
- package/src/formats/gml/exporter.ts +1 -1
- package/src/formats/json/dialect.ts +37 -7
- package/src/formats/json/importer.ts +210 -132
- package/src/formats/json/obographs.ts +563 -0
- package/src/formats/obo/importer.ts +1695 -0
- package/src/formats/obo/index.ts +7 -0
- package/src/formats/obo/syntax.ts +466 -0
- package/src/index.ts +11 -0
- package/src/registry.ts +8 -1
- package/src/sniff.ts +48 -5
- package/dist/chunks/importer-B6rKRxzv.js.map +0 -1
- package/dist/chunks/writer-DHHfHn11.js.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `@graphty/graph-io/cx2` subpath (design/graph-io/cytoscape-and-obo/design.md section 1.3):
|
|
3
|
+
* the CX2 importer and exporter with their option types and code tables.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { CX2_CAPABILITIES, CX2_LOSS, cx2Exporter, type Cx2ExportOptions } from "./exporter.js";
|
|
7
|
+
export { CX2_ISSUE, cx2Importer, type Cx2ImportOptions } from "./importer.js";
|
|
@@ -73,6 +73,8 @@ export const GEXF_LOSS = Object.freeze({
|
|
|
73
73
|
DECLARED_TYPE: "W_DECLARED_TYPE",
|
|
74
74
|
/** A node id whose text reads back as the other type under the canonical rule (design section 4.1): a non-integer number, a string of integer text. */
|
|
75
75
|
ID_TEXT_TYPE: LOSS.ID_TEXT_TYPE,
|
|
76
|
+
/** A numeric edge id column: GEXF edge ids read back as strings. */
|
|
77
|
+
EDGE_ID_TEXT: "W_GEXF_EDGE_ID_TEXT",
|
|
76
78
|
/** A viz role column (position, color, size, thickness) that is not f32; the importer reads viz values as f32. */
|
|
77
79
|
VIZ_DTYPE: "W_GEXF_VIZ_DTYPE",
|
|
78
80
|
/** A plain `weight` edge column reads back as THE weight (the importer's weightFrom default). */
|
|
@@ -267,6 +269,15 @@ function planExport(
|
|
|
267
269
|
typeChanges,
|
|
268
270
|
);
|
|
269
271
|
}
|
|
272
|
+
const edgeIds = snapshot.edges.byRole("id");
|
|
273
|
+
if (edgeIds !== null && edgeIds.dtype !== "string" && edgeIds.dtype !== "dict") {
|
|
274
|
+
note(
|
|
275
|
+
GEXF_LOSS.EDGE_ID_TEXT,
|
|
276
|
+
`edge id column "${edgeIds.meta.name}" is ${edgeIds.dtype}; GEXF edge ids read back as strings`,
|
|
277
|
+
edgeIds.meta.name,
|
|
278
|
+
snapshot.edgeCount - edgeIds.nullCount,
|
|
279
|
+
);
|
|
280
|
+
}
|
|
270
281
|
const tables = collectTemporalTables(snapshot, version, note);
|
|
271
282
|
const nodeRoles = collectRoles(snapshot.nodes, "node", note);
|
|
272
283
|
const edgeRoles = collectRoles(snapshot.edges, "edge", note);
|
|
@@ -51,6 +51,7 @@ import {
|
|
|
51
51
|
} from "../../common/attributes.js";
|
|
52
52
|
import {
|
|
53
53
|
COUNT_HINT_CODE,
|
|
54
|
+
DUPLICATE_ATTRIBUTE_CODE,
|
|
54
55
|
DUPLICATE_EDGE_ID_CODE,
|
|
55
56
|
DUPLICATE_NODE_CODE,
|
|
56
57
|
ID_MERGED_CODE,
|
|
@@ -122,8 +123,6 @@ export const ATTRIBUTES_CLASS_CODE = "E_GEXF_ATTRIBUTES_CLASS";
|
|
|
122
123
|
export const ATTRIBUTE_ID_CODE = "E_GEXF_ATTRIBUTE_ID";
|
|
123
124
|
/** Issue code: a graph header value (`defaultedgetype`, `mode`, `timeformat`, ...) outside its set. */
|
|
124
125
|
export const HEADER_VALUE_CODE = "W_GEXF_HEADER_VALUE";
|
|
125
|
-
/** Issue code: a second `<attribute>` with the same id in the same class (the first is kept). */
|
|
126
|
-
export const DUPLICATE_ATTRIBUTE_CODE = "W_GEXF_DUPLICATE_ATTRIBUTE";
|
|
127
126
|
/** Issue code: an `<attribute>` without a type (read as string). */
|
|
128
127
|
export const ATTRIBUTE_TYPE_CODE = "W_GEXF_ATTRIBUTE_TYPE";
|
|
129
128
|
/** Issue code: an `<attvalue>` naming an attribute the document never declares (once per id). */
|
|
@@ -149,6 +148,7 @@ export const VIZ_VALUE_CODE = "W_GEXF_VIZ_VALUE";
|
|
|
149
148
|
export const OPEN_BOUND_CONFLICT_CODE = "W_GEXF_OPEN_BOUND_CONFLICT";
|
|
150
149
|
|
|
151
150
|
export {
|
|
151
|
+
DUPLICATE_ATTRIBUTE_CODE,
|
|
152
152
|
DUPLICATE_NODE_CODE,
|
|
153
153
|
ID_MERGED_CODE,
|
|
154
154
|
MISSING_ENDPOINT_CODE,
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
COUNT_HINT_CODE,
|
|
12
12
|
DIRECTION_FORCED_CODE,
|
|
13
13
|
DIRECTION_REFUSED_CODE,
|
|
14
|
+
DUPLICATE_ATTRIBUTE_CODE,
|
|
14
15
|
DUPLICATE_EDGE_ID_CODE,
|
|
15
16
|
DUPLICATE_NODE_CODE,
|
|
16
17
|
ENCODING_FALLBACK_CODE,
|
|
@@ -37,7 +38,6 @@ import {
|
|
|
37
38
|
ATTRIBUTE_TYPE_CODE,
|
|
38
39
|
ATTRIBUTES_CLASS_CODE,
|
|
39
40
|
ATTVALUE_SHAPE_CODE,
|
|
40
|
-
DUPLICATE_ATTRIBUTE_CODE,
|
|
41
41
|
EDGE_TYPE_CODE,
|
|
42
42
|
HEADER_VALUE_CODE,
|
|
43
43
|
MISSING_NODES_CODE,
|
|
@@ -140,7 +140,7 @@ const SKIPPED_ROLES: ReadonlySet<string> = new Set([
|
|
|
140
140
|
]);
|
|
141
141
|
|
|
142
142
|
const NODE_RESERVED: ReadonlySet<string> = new Set(["id"]);
|
|
143
|
-
const EDGE_RESERVED: ReadonlySet<string> = new Set(["source", "target"]);
|
|
143
|
+
const EDGE_RESERVED: ReadonlySet<string> = new Set(["source", "target", "directed"]);
|
|
144
144
|
const GRAPH_RESERVED: ReadonlySet<string> = new Set(["node", "edge", "directed", "multigraph"]);
|
|
145
145
|
const TOP_RESERVED: ReadonlySet<string> = new Set(["graph"]);
|
|
146
146
|
const NUMBER_TEXT = /^[+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?$/;
|
|
@@ -32,17 +32,19 @@ export const JSON_DIALECTS: readonly JsonDialect[] = Object.freeze([
|
|
|
32
32
|
]);
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
* The dialects the importer reads: every JsonDialect plus
|
|
36
|
-
* adjacency_data (`nodes` plus one neighbour list per node under `adjacency`)
|
|
37
|
-
* nested `id` / `children` record)
|
|
35
|
+
* The dialects the importer reads: every JsonDialect plus three it only reads, NetworkX
|
|
36
|
+
* adjacency_data (`nodes` plus one neighbour list per node under `adjacency`), tree_data (a
|
|
37
|
+
* nested `id` / `children` record) and OBO Graphs (`graphs[]` of `sub` / `pred` / `obj` edges, the
|
|
38
|
+
* JSON form of the Gene Ontology and the OBO Foundry ontologies). The exporter writes none of them.
|
|
38
39
|
*/
|
|
39
|
-
export type JsonImportDialect = JsonDialect | "adjacency" | "tree";
|
|
40
|
+
export type JsonImportDialect = JsonDialect | "adjacency" | "tree" | "obographs";
|
|
40
41
|
|
|
41
42
|
/** Every dialect the importer reads, for option checking and messages. */
|
|
42
43
|
export const JSON_IMPORT_DIALECTS: readonly JsonImportDialect[] = Object.freeze([
|
|
43
44
|
...JSON_DIALECTS,
|
|
44
45
|
"adjacency",
|
|
45
46
|
"tree",
|
|
47
|
+
"obographs",
|
|
46
48
|
]);
|
|
47
49
|
|
|
48
50
|
/** The key under `meta.extra` that holds the shape record (design section 8.5). */
|
|
@@ -116,8 +118,9 @@ export function isJsonImportDialect(value: unknown): value is JsonImportDialect
|
|
|
116
118
|
|
|
117
119
|
/**
|
|
118
120
|
* The dialect of a parsed JSON document, by the shape rules of design section 8.2 (Cytoscape:
|
|
119
|
-
* `elements` or a top-level array of `{ data }` elements;
|
|
120
|
-
*
|
|
121
|
+
* `elements` or a top-level array of `{ data }` elements; OBO Graphs: `graphs[]` whose first graph
|
|
122
|
+
* has an edge with `sub` (or `subj`) and `obj` or a `pred`, or a node with `lbl`, `meta` or an OWL
|
|
123
|
+
* `type`; JGF: `graph.nodes` / `graph.edges` or any other `graphs[]`; graphology: `options.type` / `options.multi`, `key` nodes without `id`, edges with
|
|
121
124
|
* `undirected` or an `attributes` record; vis: edges with `from` / `to`; d3: `links` without
|
|
122
125
|
* `directed` / `multigraph` / `graph`; NetworkX adjacency_data: `nodes` and `adjacency` without
|
|
123
126
|
* `links` / `edges`; NetworkX tree_data: `children` without `nodes` / `links` / `edges`; else
|
|
@@ -141,7 +144,7 @@ export function sniffJsonDialect(root: unknown): JsonImportDialect | null {
|
|
|
141
144
|
return "jgf";
|
|
142
145
|
}
|
|
143
146
|
if (Array.isArray(root.graphs)) {
|
|
144
|
-
return "jgf";
|
|
147
|
+
return isOboGraph(firstJsonObject(root.graphs)) ? "obographs" : "jgf";
|
|
145
148
|
}
|
|
146
149
|
if (!hasKey(root, "edges") && !hasKey(root, "links")) {
|
|
147
150
|
if (hasKey(root, "nodes") && hasKey(root, "adjacency")) {
|
|
@@ -171,6 +174,31 @@ export function sniffJsonDialect(root: unknown): JsonImportDialect | null {
|
|
|
171
174
|
return bare && hasKey(root, "links") ? "d3" : "node-link";
|
|
172
175
|
}
|
|
173
176
|
|
|
177
|
+
/** The node types of OBO Graphs (the OWL entity kinds). */
|
|
178
|
+
const OBOGRAPHS_NODE_TYPES: ReadonlySet<unknown> = new Set(["CLASS", "INDIVIDUAL", "PROPERTY"]);
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Whether a graph of a `graphs[]` document is an OBO Graphs graph rather than JGF: anywhere in its
|
|
182
|
+
* nodes or edges, an edge with `sub` (or the outdated `subj`) and `obj`, or a `pred`, or a node
|
|
183
|
+
* with `lbl`, `meta` or a `type` of CLASS / INDIVIDUAL / PROPERTY (design 1.6: looking only at the
|
|
184
|
+
* first node and edge misses graphs with no edges and graphs whose first node has no `lbl`).
|
|
185
|
+
* @param graph - the first graph, or null
|
|
186
|
+
* @returns true for OBO Graphs
|
|
187
|
+
*/
|
|
188
|
+
function isOboGraph(graph: Record<string, unknown> | null): boolean {
|
|
189
|
+
if (graph === null) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
const isEdge = (e: unknown): boolean =>
|
|
193
|
+
isJsonObject(e) && ((hasKey(e, "obj") && (hasKey(e, "sub") || hasKey(e, "subj"))) || hasKey(e, "pred"));
|
|
194
|
+
const isNode = (n: unknown): boolean =>
|
|
195
|
+
isJsonObject(n) && (hasKey(n, "lbl") || hasKey(n, "meta") || OBOGRAPHS_NODE_TYPES.has(n.type));
|
|
196
|
+
return (
|
|
197
|
+
(Array.isArray(graph.edges) && graph.edges.some(isEdge)) ||
|
|
198
|
+
(Array.isArray(graph.nodes) && graph.nodes.some(isNode))
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
174
202
|
/**
|
|
175
203
|
* The first object of an array, or null.
|
|
176
204
|
* @param value - maybe an array
|
|
@@ -223,6 +251,8 @@ export const DIALECT_DEFAULT_DIRECTED: Readonly<Record<JsonImportDialect, boolea
|
|
|
223
251
|
// networkx adjacency_data declares `directed`; tree_graph always builds a DiGraph
|
|
224
252
|
adjacency: false,
|
|
225
253
|
tree: true,
|
|
254
|
+
// OBO Graphs edges point from the subject (child) to the object (parent)
|
|
255
|
+
obographs: true,
|
|
226
256
|
});
|
|
227
257
|
|
|
228
258
|
/**
|