@graphty/graph-io 0.3.17 → 0.3.18
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 +29 -3
- package/dist/chunks/{escape-scjHxjpr.js → escape-D-gZWO26.js} +3 -2
- package/dist/chunks/{escape-scjHxjpr.js.map → escape-D-gZWO26.js.map} +1 -1
- package/dist/chunks/{importer-Xg07gk7p.js → importer-Br_QeAeE.js} +4 -3
- package/dist/chunks/{importer-Xg07gk7p.js.map → importer-Br_QeAeE.js.map} +1 -1
- package/dist/chunks/{importer-ruMWWvVs.js → importer-DHagxvDD.js} +4 -3
- package/dist/chunks/{importer-ruMWWvVs.js.map → importer-DHagxvDD.js.map} +1 -1
- package/dist/chunks/{importer-B6rKRxzv.js → importer-Du5crN9l.js} +509 -25
- package/dist/chunks/importer-Du5crN9l.js.map +1 -0
- package/dist/chunks/importer-aNJfe0qu.js +1614 -0
- package/dist/chunks/importer-aNJfe0qu.js.map +1 -0
- package/dist/chunks/{importer-BmOl9gLW.js → importer-d0uQxFp6.js} +4 -3
- package/dist/chunks/{importer-BmOl9gLW.js.map → importer-d0uQxFp6.js.map} +1 -1
- package/dist/chunks/ontology-BnrJ4I98.js +113 -0
- package/dist/chunks/ontology-BnrJ4I98.js.map +1 -0
- package/dist/chunks/{records-DSpbTE5s.js → records-Bk9jgodz.js} +2 -2
- package/dist/chunks/{records-DSpbTE5s.js.map → records-Bk9jgodz.js.map} +1 -1
- package/dist/chunks/{writer-DHHfHn11.js → report-BOk0p5y8.js} +97 -919
- package/dist/chunks/report-BOk0p5y8.js.map +1 -0
- package/dist/chunks/writer-GAdltGmC.js +827 -0
- package/dist/chunks/writer-GAdltGmC.js.map +1 -0
- package/dist/csv.js +4 -3
- package/dist/csv.js.map +1 -1
- package/dist/dot.js +1 -1
- package/dist/gexf.js +3 -2
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +3 -2
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +160 -141
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +1 -1
- package/dist/json.js +1 -1
- package/dist/neo4j.js +4 -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/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/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 +153 -22
- 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 +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +3 -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 +23 -3
- package/dist/src/sniff.js.map +1 -1
- package/package.json +6 -1
- package/src/common/ontology.ts +169 -0
- package/src/formats/json/dialect.ts +37 -7
- package/src/formats/json/importer.ts +204 -27
- 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 +1 -0
- package/src/registry.ts +3 -1
- package/src/sniff.ts +35 -5
- package/dist/chunks/importer-B6rKRxzv.js.map +0 -1
- package/dist/chunks/writer-DHHfHn11.js.map +0 -1
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
|
|
2
|
-
import {
|
|
2
|
+
import { aC as resolveExportOptions, ay as pairFolding, as as declareResolved, ag as UNKNOWN_ENCODING_CODE, s as ENCODING_FALLBACK_CODE, z as INVALID_ENCODING_CODE, F as INVALID_UTF8_CODE, V as OPTION_IGNORED_CODE, a3 as SINK_OPTION_CODE, H as HYPEREDGE_CODE, ad as TOO_LARGE_CODE, D as DANGLING_REFERENCE_CODE, A as AMBIGUOUS_GRAPH_NAME_CODE, G as GRAPH_NOT_FOUND_CODE, P as MULTIPLE_GRAPHS_CODE, v as ID_MERGED_CODE, n as DUPLICATE_EDGE_ID_CODE, p as DUPLICATE_NODE_CODE, ah as UNKNOWN_PARENT_CODE, e as BAD_VALUE_CODE, M as MISSING_ENDPOINT_CODE, N as MISSING_ID_CODE, a9 as SYNTAX_CODE, r as EMPTY_INPUT_CODE, aD as resolveImportOptions, I as ImportReportBuilder, az as readText, t as textChunks, aA as reportSinkOptions, aB as reportUnusedOptions, a as throwIfAborted, J as IdCoercer, q as DirectionResolver, aE as uniqueColumnName, ao as chooseGraph } from "./report-BOk0p5y8.js";
|
|
3
|
+
import { c as capabilities, L as LOSS, n as joinText, e as encodeChunks, a as checkCapabilities, r as countMixedEdges, f as explicitWeights, h as formatF32, i as formatF64, w as weightFromValue } from "./writer-GAdltGmC.js";
|
|
4
|
+
import { a as OBOGRAPHS_PREDICATE_TAGS, c as compactOboIri, o as oboColumnDecl, P as PLACEHOLDER_COLUMN, s as synonymScopeOf, O as OBO_NODE_COLUMNS } from "./ontology-BnrJ4I98.js";
|
|
3
5
|
const JSON_DIALECTS = Object.freeze([
|
|
4
6
|
"node-link",
|
|
5
7
|
"d3",
|
|
@@ -11,7 +13,8 @@ const JSON_DIALECTS = Object.freeze([
|
|
|
11
13
|
const JSON_IMPORT_DIALECTS = Object.freeze([
|
|
12
14
|
...JSON_DIALECTS,
|
|
13
15
|
"adjacency",
|
|
14
|
-
"tree"
|
|
16
|
+
"tree",
|
|
17
|
+
"obographs"
|
|
15
18
|
]);
|
|
16
19
|
const META_KEY = "json";
|
|
17
20
|
function isJsonObject(value) {
|
|
@@ -41,7 +44,7 @@ function sniffJsonDialect(root) {
|
|
|
41
44
|
return "jgf";
|
|
42
45
|
}
|
|
43
46
|
if (Array.isArray(root.graphs)) {
|
|
44
|
-
return "jgf";
|
|
47
|
+
return isOboGraph(firstJsonObject(root.graphs)) ? "obographs" : "jgf";
|
|
45
48
|
}
|
|
46
49
|
if (!hasKey(root, "edges") && !hasKey(root, "links")) {
|
|
47
50
|
if (hasKey(root, "nodes") && hasKey(root, "adjacency")) {
|
|
@@ -70,6 +73,15 @@ function sniffJsonDialect(root) {
|
|
|
70
73
|
const bare = !hasKey(root, "directed") && !hasKey(root, "multigraph") && !hasKey(root, "graph");
|
|
71
74
|
return bare && hasKey(root, "links") ? "d3" : "node-link";
|
|
72
75
|
}
|
|
76
|
+
const OBOGRAPHS_NODE_TYPES = /* @__PURE__ */ new Set(["CLASS", "INDIVIDUAL", "PROPERTY"]);
|
|
77
|
+
function isOboGraph(graph) {
|
|
78
|
+
if (graph === null) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
const isEdge = (e) => isJsonObject(e) && (hasKey(e, "obj") && (hasKey(e, "sub") || hasKey(e, "subj")) || hasKey(e, "pred"));
|
|
82
|
+
const isNode = (n) => isJsonObject(n) && (hasKey(n, "lbl") || hasKey(n, "meta") || OBOGRAPHS_NODE_TYPES.has(n.type));
|
|
83
|
+
return Array.isArray(graph.edges) && graph.edges.some(isEdge) || Array.isArray(graph.nodes) && graph.nodes.some(isNode);
|
|
84
|
+
}
|
|
73
85
|
function firstJsonObject(value) {
|
|
74
86
|
if (!Array.isArray(value)) {
|
|
75
87
|
return null;
|
|
@@ -107,7 +119,9 @@ const DIALECT_DEFAULT_DIRECTED = Object.freeze({
|
|
|
107
119
|
vis: false,
|
|
108
120
|
// networkx adjacency_data declares `directed`; tree_graph always builds a DiGraph
|
|
109
121
|
adjacency: false,
|
|
110
|
-
tree: true
|
|
122
|
+
tree: true,
|
|
123
|
+
// OBO Graphs edges point from the subject (child) to the object (parent)
|
|
124
|
+
obographs: true
|
|
111
125
|
});
|
|
112
126
|
const JSON_DTYPES = Object.freeze(["f64", "i32", "bool", "string"]);
|
|
113
127
|
const COMMON = {
|
|
@@ -1356,6 +1370,383 @@ const jsonExporter = Object.freeze({
|
|
|
1356
1370
|
function jsonCapabilities(dialect) {
|
|
1357
1371
|
return dialectCapabilities(dialect);
|
|
1358
1372
|
}
|
|
1373
|
+
const NODE_KEYS = /* @__PURE__ */ new Set(["id", "lbl", "type", "propertyType", "meta"]);
|
|
1374
|
+
const META_KEYS = /* @__PURE__ */ new Set([
|
|
1375
|
+
"definition",
|
|
1376
|
+
"comments",
|
|
1377
|
+
"subsets",
|
|
1378
|
+
"xrefs",
|
|
1379
|
+
"synonyms",
|
|
1380
|
+
"basicPropertyValues",
|
|
1381
|
+
"deprecated"
|
|
1382
|
+
]);
|
|
1383
|
+
const FRAME_TYPES = Object.freeze({
|
|
1384
|
+
CLASS: "Term",
|
|
1385
|
+
INDIVIDUAL: "Instance",
|
|
1386
|
+
PROPERTY: "Typedef"
|
|
1387
|
+
});
|
|
1388
|
+
const BUILTIN_PREDICATES = Object.freeze({
|
|
1389
|
+
is_a: "is_a",
|
|
1390
|
+
subPropertyOf: "is_a",
|
|
1391
|
+
type: "instance_of",
|
|
1392
|
+
inverseOf: "inverse_of"
|
|
1393
|
+
});
|
|
1394
|
+
const PROPERTY_PREDICATES = /* @__PURE__ */ new Set(["subPropertyOf", "inverseOf"]);
|
|
1395
|
+
class ColumnWriter {
|
|
1396
|
+
/**
|
|
1397
|
+
* Create a writer.
|
|
1398
|
+
* @param ctx - the import context
|
|
1399
|
+
*/
|
|
1400
|
+
constructor(ctx) {
|
|
1401
|
+
this.handles = /* @__PURE__ */ new Map();
|
|
1402
|
+
this.ctx = ctx;
|
|
1403
|
+
}
|
|
1404
|
+
/**
|
|
1405
|
+
* Write a node cell of the vocabulary.
|
|
1406
|
+
* @param name - the column
|
|
1407
|
+
* @param row - the node index
|
|
1408
|
+
* @param value - the value
|
|
1409
|
+
*/
|
|
1410
|
+
node(name, row, value) {
|
|
1411
|
+
this.ctx.sink.setNodeValue(this.handle("node", name), row, value);
|
|
1412
|
+
}
|
|
1413
|
+
/**
|
|
1414
|
+
* Write an edge cell of the vocabulary.
|
|
1415
|
+
* @param name - the column
|
|
1416
|
+
* @param row - the edge index
|
|
1417
|
+
* @param value - the value
|
|
1418
|
+
*/
|
|
1419
|
+
edge(name, row, value) {
|
|
1420
|
+
this.ctx.sink.setEdgeValue(this.handle("edge", name), row, value);
|
|
1421
|
+
}
|
|
1422
|
+
/**
|
|
1423
|
+
* The handle of a column, declared on first use.
|
|
1424
|
+
* @param domain - node or edge
|
|
1425
|
+
* @param name - the column
|
|
1426
|
+
* @returns the handle
|
|
1427
|
+
*/
|
|
1428
|
+
handle(domain, name) {
|
|
1429
|
+
const key = `${domain}:${name}`;
|
|
1430
|
+
const cached = this.handles.get(key);
|
|
1431
|
+
if (cached !== void 0) {
|
|
1432
|
+
return cached;
|
|
1433
|
+
}
|
|
1434
|
+
const { handle } = declareResolved(this.ctx.sink, domain, oboColumnDecl(domain, name), this.ctx.report);
|
|
1435
|
+
this.handles.set(key, handle);
|
|
1436
|
+
return handle;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
function vocabularyOf(nodes, oboIds) {
|
|
1440
|
+
const shorthands = /* @__PURE__ */ new Map();
|
|
1441
|
+
const propertyIds = /* @__PURE__ */ new Set();
|
|
1442
|
+
for (const node of nodes) {
|
|
1443
|
+
if (!isJsonObject(node) || typeof node.id !== "string" || node.type !== "PROPERTY") {
|
|
1444
|
+
continue;
|
|
1445
|
+
}
|
|
1446
|
+
propertyIds.add(node.id);
|
|
1447
|
+
const shorthand = basicValues(node.meta).find((pv) => OBOGRAPHS_PREDICATE_TAGS.get(pv.pred) === "shorthand");
|
|
1448
|
+
if (shorthand !== void 0) {
|
|
1449
|
+
shorthands.set(node.id, shorthand.val);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
const compact = (iri) => oboIds === "curie" ? compactOboIri(iri) : iri;
|
|
1453
|
+
return {
|
|
1454
|
+
id: (iri) => oboIds === "curie" ? shorthands.get(iri) ?? compactOboIri(iri) : iri,
|
|
1455
|
+
relation: (pred) => BUILTIN_PREDICATES[pred] ?? shorthands.get(pred) ?? compact(pred),
|
|
1456
|
+
isProperty: (iri) => propertyIds.has(iri),
|
|
1457
|
+
properties: {}
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1460
|
+
function basicValues(meta) {
|
|
1461
|
+
if (!isJsonObject(meta) || !Array.isArray(meta.basicPropertyValues)) {
|
|
1462
|
+
return [];
|
|
1463
|
+
}
|
|
1464
|
+
return meta.basicPropertyValues.filter(
|
|
1465
|
+
(pv) => isJsonObject(pv) && typeof pv.pred === "string" && typeof pv.val === "string"
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
function strings(value) {
|
|
1469
|
+
if (!Array.isArray(value)) {
|
|
1470
|
+
return [];
|
|
1471
|
+
}
|
|
1472
|
+
return value.flatMap((item) => {
|
|
1473
|
+
if (typeof item === "string") {
|
|
1474
|
+
return [item];
|
|
1475
|
+
}
|
|
1476
|
+
return isJsonObject(item) && typeof item.val === "string" ? [item.val] : [];
|
|
1477
|
+
});
|
|
1478
|
+
}
|
|
1479
|
+
function importObographs(ctx, root) {
|
|
1480
|
+
const graph = chosenGraph(ctx, root, "OBO Graphs");
|
|
1481
|
+
const nodes = sectionOf(ctx, graph, "nodes");
|
|
1482
|
+
const edges = sectionOf(ctx, graph, "edges");
|
|
1483
|
+
const vocabulary = vocabularyOf(nodes, ctx.json.oboIds);
|
|
1484
|
+
const columns = new ColumnWriter(ctx);
|
|
1485
|
+
ctx.reportNodeIdFrom("obographs", "the node ids");
|
|
1486
|
+
ctx.setHeader(true);
|
|
1487
|
+
ctx.sink.reserve(nodes.length, edges.length);
|
|
1488
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
1489
|
+
readNode(ctx, columns, vocabulary, nodes[i], `nodes[${i}]`);
|
|
1490
|
+
}
|
|
1491
|
+
const propertyEdges = readEdges(ctx, columns, vocabulary, edges);
|
|
1492
|
+
const graphMeta = {};
|
|
1493
|
+
for (const key of Object.keys(graph)) {
|
|
1494
|
+
if (key !== "nodes" && key !== "edges") {
|
|
1495
|
+
graphMeta[key] = graph[key];
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
const document = {};
|
|
1499
|
+
for (const key of Object.keys(root)) {
|
|
1500
|
+
if (key !== "graphs") {
|
|
1501
|
+
document[key] = root[key];
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
const label = typeof graph.lbl === "string" ? graph.lbl : null;
|
|
1505
|
+
const name = label ?? (typeof graph.id === "string" ? graph.id : null);
|
|
1506
|
+
ctx.sink.setMeta({
|
|
1507
|
+
sourceFormat: "json",
|
|
1508
|
+
name,
|
|
1509
|
+
extra: {
|
|
1510
|
+
json: { dialect: "obographs" },
|
|
1511
|
+
obographs: {
|
|
1512
|
+
ids: ctx.json.oboIds,
|
|
1513
|
+
graph: graphMeta,
|
|
1514
|
+
document,
|
|
1515
|
+
properties: vocabulary.properties,
|
|
1516
|
+
propertyEdges
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
});
|
|
1520
|
+
}
|
|
1521
|
+
function sectionOf(ctx, graph, key) {
|
|
1522
|
+
const value = graph[key];
|
|
1523
|
+
if (value === void 0 || value === null) {
|
|
1524
|
+
return [];
|
|
1525
|
+
}
|
|
1526
|
+
if (!Array.isArray(value)) {
|
|
1527
|
+
return ctx.report.fail(JSON_ISSUE.SHAPE, `an OBO Graphs graph's ${key} must be an array`, { element: key });
|
|
1528
|
+
}
|
|
1529
|
+
return value;
|
|
1530
|
+
}
|
|
1531
|
+
function readNode(ctx, columns, vocabulary, record, element) {
|
|
1532
|
+
if (!isJsonObject(record)) {
|
|
1533
|
+
ctx.badElement("node", element);
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1536
|
+
if (typeof record.id !== "string") {
|
|
1537
|
+
if (record.id === void 0) {
|
|
1538
|
+
ctx.coerceId(void 0, element);
|
|
1539
|
+
} else {
|
|
1540
|
+
badValue(ctx, `${element}.id must be a string; the node is skipped`);
|
|
1541
|
+
}
|
|
1542
|
+
ctx.countSkipped("node");
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
1545
|
+
if (record.type === "PROPERTY" && ctx.json.typedefs === "metadata") {
|
|
1546
|
+
const shorthand = vocabulary.id(record.id) === record.id ? void 0 : vocabulary.id(record.id);
|
|
1547
|
+
const entry = {};
|
|
1548
|
+
for (const [key, value] of Object.entries({
|
|
1549
|
+
lbl: record.lbl,
|
|
1550
|
+
propertyType: record.propertyType,
|
|
1551
|
+
shorthand,
|
|
1552
|
+
meta: record.meta
|
|
1553
|
+
})) {
|
|
1554
|
+
if (value !== void 0) {
|
|
1555
|
+
entry[key] = value;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
vocabulary.properties[record.id] = entry;
|
|
1559
|
+
return;
|
|
1560
|
+
}
|
|
1561
|
+
const id = ctx.coerceId(vocabulary.id(record.id), element);
|
|
1562
|
+
const row = id === null ? -1 : ctx.pushNode(id, element);
|
|
1563
|
+
if (row < 0) {
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
try {
|
|
1567
|
+
writeNode(ctx, columns, vocabulary, record, row, element);
|
|
1568
|
+
} catch (err) {
|
|
1569
|
+
ctx.report.recordError(err, { element: record.id });
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
function writeNode(ctx, columns, vocabulary, record, row, element) {
|
|
1573
|
+
const unrecognized = {};
|
|
1574
|
+
const text = (key, column) => {
|
|
1575
|
+
const value = record[key];
|
|
1576
|
+
if (typeof value === "string") {
|
|
1577
|
+
columns.node(column, row, column === "type" ? FRAME_TYPES[value] ?? value : value);
|
|
1578
|
+
} else if (value !== void 0 && value !== null) {
|
|
1579
|
+
badValue(ctx, `${element}.${key} must be a string`);
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
text("type", "type");
|
|
1583
|
+
text("lbl", "name");
|
|
1584
|
+
text("propertyType", "propertyType");
|
|
1585
|
+
for (const key of Object.keys(record)) {
|
|
1586
|
+
if (!NODE_KEYS.has(key)) {
|
|
1587
|
+
unrecognized[key] = record[key];
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
const { meta } = record;
|
|
1591
|
+
if (isJsonObject(meta)) {
|
|
1592
|
+
writeMeta(columns, vocabulary, meta, row, unrecognized);
|
|
1593
|
+
} else if (meta !== void 0 && meta !== null) {
|
|
1594
|
+
badValue(ctx, `${element}.meta must be an object`);
|
|
1595
|
+
}
|
|
1596
|
+
if (Object.keys(unrecognized).length > 0) {
|
|
1597
|
+
columns.node("obo.unrecognized", row, unrecognized);
|
|
1598
|
+
}
|
|
1599
|
+
}
|
|
1600
|
+
function writeMeta(columns, vocabulary, meta, row, unrecognized) {
|
|
1601
|
+
const { definition } = meta;
|
|
1602
|
+
if (isJsonObject(definition) && typeof definition.val === "string") {
|
|
1603
|
+
columns.node("def", row, definition.val);
|
|
1604
|
+
columns.node("def.xrefs", row, strings(definition.xrefs));
|
|
1605
|
+
}
|
|
1606
|
+
const comments = strings(meta.comments);
|
|
1607
|
+
if (comments.length > 0) {
|
|
1608
|
+
columns.node("comment", row, comments.join("\n"));
|
|
1609
|
+
}
|
|
1610
|
+
const subsets = strings(meta.subsets).map((s) => vocabulary.id(s));
|
|
1611
|
+
if (subsets.length > 0) {
|
|
1612
|
+
columns.node("subset", row, subsets);
|
|
1613
|
+
}
|
|
1614
|
+
const xrefs = strings(meta.xrefs);
|
|
1615
|
+
if (xrefs.length > 0) {
|
|
1616
|
+
columns.node("xref", row, xrefs);
|
|
1617
|
+
}
|
|
1618
|
+
if (Array.isArray(meta.synonyms) && meta.synonyms.length > 0) {
|
|
1619
|
+
columns.node(
|
|
1620
|
+
"synonym",
|
|
1621
|
+
row,
|
|
1622
|
+
meta.synonyms.filter(isJsonObject).map((s) => ({
|
|
1623
|
+
text: typeof s.val === "string" ? s.val : null,
|
|
1624
|
+
scope: typeof s.pred === "string" ? synonymScopeOf(s.pred) : null,
|
|
1625
|
+
type: typeof s.synonymType === "string" ? vocabulary.id(s.synonymType) : null,
|
|
1626
|
+
xrefs: strings(s.xrefs)
|
|
1627
|
+
}))
|
|
1628
|
+
);
|
|
1629
|
+
}
|
|
1630
|
+
if (typeof meta.deprecated === "boolean") {
|
|
1631
|
+
columns.node("is_obsolete", row, meta.deprecated);
|
|
1632
|
+
}
|
|
1633
|
+
writePropertyValues(columns, vocabulary, basicValues(meta), row);
|
|
1634
|
+
for (const key of Object.keys(meta)) {
|
|
1635
|
+
if (!META_KEYS.has(key)) {
|
|
1636
|
+
unrecognized[`meta.${key}`] = meta[key];
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
function writePropertyValues(columns, vocabulary, values, row) {
|
|
1641
|
+
const lists = /* @__PURE__ */ new Map();
|
|
1642
|
+
const others = [];
|
|
1643
|
+
for (const { pred, val } of values) {
|
|
1644
|
+
const tag = OBOGRAPHS_PREDICATE_TAGS.get(pred);
|
|
1645
|
+
if (tag === "shorthand") {
|
|
1646
|
+
continue;
|
|
1647
|
+
}
|
|
1648
|
+
if (tag === void 0) {
|
|
1649
|
+
others.push({ relation: vocabulary.id(pred), value: val, datatype: null });
|
|
1650
|
+
} else if (OBO_NODE_COLUMNS[tag].dtype === "list") {
|
|
1651
|
+
const list = lists.get(tag) ?? [];
|
|
1652
|
+
list.push(tag === "alt_id" ? val : vocabulary.id(val));
|
|
1653
|
+
lists.set(tag, list);
|
|
1654
|
+
} else {
|
|
1655
|
+
columns.node(tag, row, val);
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
for (const [tag, list] of lists) {
|
|
1659
|
+
columns.node(tag, row, list);
|
|
1660
|
+
}
|
|
1661
|
+
if (others.length > 0) {
|
|
1662
|
+
columns.node("property_value", row, others);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
function badValue(ctx, message) {
|
|
1666
|
+
ctx.report.error("validation-error", JSON_ISSUE.BAD_VALUE, message);
|
|
1667
|
+
}
|
|
1668
|
+
function readEdges(ctx, columns, vocabulary, edges) {
|
|
1669
|
+
const { report, sink } = ctx;
|
|
1670
|
+
const propertyEdges = [];
|
|
1671
|
+
const dangling = [];
|
|
1672
|
+
let dropped = 0;
|
|
1673
|
+
const endpoint = (raw, element) => {
|
|
1674
|
+
const id = ctx.coerceId(vocabulary.id(raw), element);
|
|
1675
|
+
if (id === null || sink.indexOf(id) !== INVALID_INDEX) {
|
|
1676
|
+
return id;
|
|
1677
|
+
}
|
|
1678
|
+
dangling.push(raw);
|
|
1679
|
+
if (!ctx.options.addMissingNodes) {
|
|
1680
|
+
return null;
|
|
1681
|
+
}
|
|
1682
|
+
const row = ctx.pushNode(id, element);
|
|
1683
|
+
if (row >= 0) {
|
|
1684
|
+
columns.node(PLACEHOLDER_COLUMN, row, true);
|
|
1685
|
+
}
|
|
1686
|
+
return id;
|
|
1687
|
+
};
|
|
1688
|
+
for (let i = 0; i < edges.length; i++) {
|
|
1689
|
+
const element = `edges[${i}]`;
|
|
1690
|
+
const record = edges[i];
|
|
1691
|
+
if (!isJsonObject(record)) {
|
|
1692
|
+
ctx.badElement("edge", element);
|
|
1693
|
+
continue;
|
|
1694
|
+
}
|
|
1695
|
+
const subKey = hasKey(record, "sub") ? "sub" : "subj";
|
|
1696
|
+
if (subKey === "subj" && hasKey(record, "subj")) {
|
|
1697
|
+
report.warnOnce(
|
|
1698
|
+
"coercion",
|
|
1699
|
+
JSON_ISSUE.OBOGRAPHS_SUBJ,
|
|
1700
|
+
`${element} uses the outdated key subj; read as sub`,
|
|
1701
|
+
{
|
|
1702
|
+
element
|
|
1703
|
+
}
|
|
1704
|
+
);
|
|
1705
|
+
}
|
|
1706
|
+
const sub = record[subKey];
|
|
1707
|
+
const { obj, pred } = record;
|
|
1708
|
+
if (typeof sub !== "string" || typeof obj !== "string") {
|
|
1709
|
+
ctx.missingEndpoint(element, typeof sub === "string" ? "obj" : "sub");
|
|
1710
|
+
continue;
|
|
1711
|
+
}
|
|
1712
|
+
const between = typeof pred === "string" && PROPERTY_PREDICATES.has(pred) || vocabulary.isProperty(sub) || vocabulary.isProperty(obj);
|
|
1713
|
+
if (between && ctx.json.typedefs === "metadata") {
|
|
1714
|
+
propertyEdges.push(record);
|
|
1715
|
+
continue;
|
|
1716
|
+
}
|
|
1717
|
+
try {
|
|
1718
|
+
const u = endpoint(sub, `${element}.sub`);
|
|
1719
|
+
const v = endpoint(obj, `${element}.obj`);
|
|
1720
|
+
if (u === null || v === null) {
|
|
1721
|
+
dropped++;
|
|
1722
|
+
ctx.countSkipped("edge");
|
|
1723
|
+
continue;
|
|
1724
|
+
}
|
|
1725
|
+
const edge = ctx.pushEdge(u, v, "directed", void 0, element);
|
|
1726
|
+
if (typeof pred === "string") {
|
|
1727
|
+
columns.edge("relation", edge, vocabulary.relation(pred));
|
|
1728
|
+
} else {
|
|
1729
|
+
badValue(ctx, `${element} has no pred; its relation is unset`);
|
|
1730
|
+
}
|
|
1731
|
+
if (isJsonObject(record.meta)) {
|
|
1732
|
+
columns.edge("meta", edge, record.meta);
|
|
1733
|
+
}
|
|
1734
|
+
} catch (err) {
|
|
1735
|
+
ctx.skip(err, "edge", element);
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
if (dangling.length > 0) {
|
|
1739
|
+
const shown = [...new Set(dangling)].slice(0, 5).join(", ");
|
|
1740
|
+
const action = ctx.options.addMissingNodes ? "each became a placeholder node (graphty.placeholder)" : `${dropped} edge(s) to them were dropped (addMissingNodes false)`;
|
|
1741
|
+
report.warning(
|
|
1742
|
+
"validation-error",
|
|
1743
|
+
JSON_ISSUE.DANGLING_REFERENCE,
|
|
1744
|
+
`${new Set(dangling).size} edge endpoint(s) missing from nodes: ${shown}; ${action}`,
|
|
1745
|
+
{ element: dangling[0] }
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
return propertyEdges;
|
|
1749
|
+
}
|
|
1359
1750
|
const JSON_ISSUE = Object.freeze({
|
|
1360
1751
|
/** The text is empty or whitespace (fatal). */
|
|
1361
1752
|
EMPTY_INPUT: EMPTY_INPUT_CODE,
|
|
@@ -1391,8 +1782,18 @@ const JSON_ISSUE = Object.freeze({
|
|
|
1391
1782
|
ID_MERGED: ID_MERGED_CODE,
|
|
1392
1783
|
/** Edge ids of mixed JSON types were stored as text. */
|
|
1393
1784
|
EDGE_ID_STRINGIFIED: "W_EDGE_ID_STRINGIFIED",
|
|
1394
|
-
/** A JGF `graphs` array holds more than one graph; only
|
|
1785
|
+
/** A JGF or OBO Graphs `graphs` array holds more than one graph; only the chosen one is read. */
|
|
1395
1786
|
MULTIPLE_GRAPHS: MULTIPLE_GRAPHS_CODE,
|
|
1787
|
+
/** `graphIndex` is beyond the `graphs` array, or `graphName` names none of its graphs (fatal). */
|
|
1788
|
+
GRAPH_NOT_FOUND: GRAPH_NOT_FOUND_CODE,
|
|
1789
|
+
/** `graphName` names more than one graph of the `graphs` array (fatal). */
|
|
1790
|
+
AMBIGUOUS_GRAPH_NAME: AMBIGUOUS_GRAPH_NAME_CODE,
|
|
1791
|
+
/** obographs: an edge uses the outdated `subj` key of the OBO Graphs README; it is read as `sub`. */
|
|
1792
|
+
OBOGRAPHS_SUBJ: "W_JSON_OBOGRAPHS_SUBJ",
|
|
1793
|
+
/** obographs: an edge endpoint missing from `nodes` (a placeholder node is made, or the edge dropped under addMissingNodes false). */
|
|
1794
|
+
DANGLING_REFERENCE: DANGLING_REFERENCE_CODE,
|
|
1795
|
+
/** The document is longer than one JavaScript string can hold (fatal; category unsupported). */
|
|
1796
|
+
TOO_LARGE: TOO_LARGE_CODE,
|
|
1396
1797
|
/** JGF hyperedges under the "error" policy. */
|
|
1397
1798
|
HYPEREDGE: HYPEREDGE_CODE,
|
|
1398
1799
|
/** JGF hyperedges skipped under the default "skip" policy. */
|
|
@@ -1475,6 +1876,14 @@ function resolveJsonOptions(options) {
|
|
|
1475
1876
|
if (!Number.isInteger(graphIndex) || graphIndex < 0) {
|
|
1476
1877
|
throw unsupportedOption("graphIndex", graphIndex, ["a non-negative integer"]);
|
|
1477
1878
|
}
|
|
1879
|
+
const oboIds = o.oboIds ?? "curie";
|
|
1880
|
+
if (oboIds !== "curie" && oboIds !== "iri") {
|
|
1881
|
+
throw unsupportedOption("oboIds", oboIds, ["curie", "iri"]);
|
|
1882
|
+
}
|
|
1883
|
+
const typedefs = o.typedefs ?? "metadata";
|
|
1884
|
+
if (typedefs !== "metadata" && typedefs !== "nodes") {
|
|
1885
|
+
throw unsupportedOption("typedefs", typedefs, ["metadata", "nodes"]);
|
|
1886
|
+
}
|
|
1478
1887
|
const nodesPath = pathOption("nodesPath", o.nodesPath);
|
|
1479
1888
|
const edgesPath = pathOption("edgesPath", o.edgesPath);
|
|
1480
1889
|
if ((nodesPath !== null || edgesPath !== null) && dialect !== "auto" && !PATH_DIALECTS.has(dialect)) {
|
|
@@ -1488,6 +1897,9 @@ function resolveJsonOptions(options) {
|
|
|
1488
1897
|
targetKey: keyOption("targetKey", o.targetKey),
|
|
1489
1898
|
indexLinks,
|
|
1490
1899
|
graphIndex,
|
|
1900
|
+
choice: { graphIndex: o.graphIndex, graphName: o.graphName },
|
|
1901
|
+
oboIds,
|
|
1902
|
+
typedefs,
|
|
1491
1903
|
nodesPath,
|
|
1492
1904
|
edgesPath
|
|
1493
1905
|
};
|
|
@@ -2059,7 +2471,7 @@ class ImportContext {
|
|
|
2059
2471
|
*/
|
|
2060
2472
|
declareEdgeIds(edges, read, name, unique) {
|
|
2061
2473
|
let numbers = 0;
|
|
2062
|
-
let
|
|
2474
|
+
let strings2 = 0;
|
|
2063
2475
|
for (const edge of edges) {
|
|
2064
2476
|
if (!isJsonObject(edge)) {
|
|
2065
2477
|
continue;
|
|
@@ -2068,16 +2480,16 @@ class ImportContext {
|
|
|
2068
2480
|
if (typeof raw === "number") {
|
|
2069
2481
|
numbers++;
|
|
2070
2482
|
} else if (typeof raw === "string") {
|
|
2071
|
-
|
|
2483
|
+
strings2++;
|
|
2072
2484
|
}
|
|
2073
2485
|
}
|
|
2074
|
-
if (numbers +
|
|
2486
|
+
if (numbers + strings2 === 0) {
|
|
2075
2487
|
return null;
|
|
2076
2488
|
}
|
|
2077
|
-
const dtype =
|
|
2489
|
+
const dtype = strings2 === 0 ? "f64" : "string";
|
|
2078
2490
|
const columnName = uniqueColumnName(name, "id", (candidate) => this.edges.taken(candidate));
|
|
2079
2491
|
const handle = this.edges.declare({ name: columnName, dtype, role: "id", nullable: true, unique });
|
|
2080
|
-
const stringify =
|
|
2492
|
+
const stringify = strings2 > 0 && numbers > 0;
|
|
2081
2493
|
const seen = unique ? /* @__PURE__ */ new Set() : null;
|
|
2082
2494
|
if (stringify) {
|
|
2083
2495
|
this.report.warning(
|
|
@@ -3029,31 +3441,84 @@ function importJgf(ctx, root) {
|
|
|
3029
3441
|
ctx.setMeta(shape, { name: label, ...ctx.weightOriginPatch() });
|
|
3030
3442
|
}
|
|
3031
3443
|
function jgfGraphOf(ctx, root) {
|
|
3444
|
+
return isJsonObject(root.graph) ? root.graph : chosenGraph(ctx, root, "JGF");
|
|
3445
|
+
}
|
|
3446
|
+
function chosenGraph(ctx, root, what) {
|
|
3032
3447
|
const { report } = ctx;
|
|
3033
|
-
if (isJsonObject(root.graph)) {
|
|
3034
|
-
return root.graph;
|
|
3035
|
-
}
|
|
3036
3448
|
const graphs = arraySection(root.graphs, "graphs", report) ?? [];
|
|
3037
3449
|
if (graphs.length === 0) {
|
|
3038
|
-
report.fail(JSON_ISSUE.SHAPE,
|
|
3450
|
+
report.fail(JSON_ISSUE.SHAPE, `a ${what} document needs a graph object or a non-empty graphs array`);
|
|
3039
3451
|
}
|
|
3452
|
+
const index = ctx.json.all === true ? ctx.json.graphIndex : chooseGraph(graphs.map(graphNameOf), ctx.json.choice, report);
|
|
3040
3453
|
if (graphs.length > 1 && ctx.json.all !== true) {
|
|
3041
3454
|
report.warning(
|
|
3042
3455
|
"unsupported",
|
|
3043
3456
|
JSON_ISSUE.MULTIPLE_GRAPHS,
|
|
3044
|
-
`the document holds ${graphs.length} graphs; only graphs[${
|
|
3457
|
+
`the document holds ${graphs.length} graphs; only graphs[${index}] is read (${graphs.length - 1} skipped), importAll() reads every one`,
|
|
3045
3458
|
{ element: "graphs" }
|
|
3046
3459
|
);
|
|
3047
3460
|
}
|
|
3048
|
-
|
|
3049
|
-
report.fail(JSON_ISSUE.SHAPE, `graphIndex ${ctx.json.graphIndex} is beyond the ${graphs.length} graph(s)`);
|
|
3050
|
-
}
|
|
3051
|
-
const graph = graphs[ctx.json.graphIndex];
|
|
3461
|
+
const graph = graphs[index];
|
|
3052
3462
|
if (!isJsonObject(graph)) {
|
|
3053
|
-
return report.fail(JSON_ISSUE.SHAPE, `graphs[${
|
|
3463
|
+
return report.fail(JSON_ISSUE.SHAPE, `graphs[${index}] is not an object`);
|
|
3054
3464
|
}
|
|
3055
3465
|
return graph;
|
|
3056
3466
|
}
|
|
3467
|
+
function graphNameOf(graph) {
|
|
3468
|
+
if (!isJsonObject(graph)) {
|
|
3469
|
+
return null;
|
|
3470
|
+
}
|
|
3471
|
+
for (const key of ["id", "label", "lbl"]) {
|
|
3472
|
+
if (typeof graph[key] === "string") {
|
|
3473
|
+
return graph[key];
|
|
3474
|
+
}
|
|
3475
|
+
}
|
|
3476
|
+
return null;
|
|
3477
|
+
}
|
|
3478
|
+
function countOf(section) {
|
|
3479
|
+
if (section === void 0 || section === null) {
|
|
3480
|
+
return 0;
|
|
3481
|
+
}
|
|
3482
|
+
if (Array.isArray(section)) {
|
|
3483
|
+
return section.length;
|
|
3484
|
+
}
|
|
3485
|
+
return isJsonObject(section) ? Object.keys(section).length : null;
|
|
3486
|
+
}
|
|
3487
|
+
function listingsOf(root, dialect) {
|
|
3488
|
+
if ((dialect === "jgf" || dialect === "obographs") && isJsonObject(root)) {
|
|
3489
|
+
if (Array.isArray(root.graphs) && !isJsonObject(root.graph)) {
|
|
3490
|
+
return root.graphs.map((graph, index) => ({
|
|
3491
|
+
index,
|
|
3492
|
+
name: graphNameOf(graph),
|
|
3493
|
+
nodes: isJsonObject(graph) ? countOf(graph.nodes) : null,
|
|
3494
|
+
edges: isJsonObject(graph) ? countOf(graph.edges) : null
|
|
3495
|
+
}));
|
|
3496
|
+
}
|
|
3497
|
+
if (isJsonObject(root.graph)) {
|
|
3498
|
+
const { graph } = root;
|
|
3499
|
+
return [{ index: 0, name: graphNameOf(graph), nodes: countOf(graph.nodes), edges: countOf(graph.edges) }];
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
return [{ index: 0, name: null, nodes: null, edges: null }];
|
|
3503
|
+
}
|
|
3504
|
+
const MAX_TEXT_LENGTH = 2 ** 29 - 24;
|
|
3505
|
+
async function readJsonText(input, report, options) {
|
|
3506
|
+
if (typeof input === "string") {
|
|
3507
|
+
return readText(input, report, options);
|
|
3508
|
+
}
|
|
3509
|
+
const parts = [];
|
|
3510
|
+
let length = 0;
|
|
3511
|
+
for await (const chunk of textChunks(input, report, options)) {
|
|
3512
|
+
length += chunk.length;
|
|
3513
|
+
if (length > MAX_TEXT_LENGTH) {
|
|
3514
|
+
const message = `the document is longer than ${MAX_TEXT_LENGTH} characters, the most one JavaScript string holds`;
|
|
3515
|
+
report.error("unsupported", JSON_ISSUE.TOO_LARGE, message);
|
|
3516
|
+
throw report.abort(message, { code: JSON_ISSUE.TOO_LARGE });
|
|
3517
|
+
}
|
|
3518
|
+
parts.push(chunk);
|
|
3519
|
+
}
|
|
3520
|
+
return parts.length === 1 ? parts[0] : parts.join("");
|
|
3521
|
+
}
|
|
3057
3522
|
function pushJgfNode(ctx, id, record, labelColumn, element) {
|
|
3058
3523
|
const index = ctx.pushNode(id, element);
|
|
3059
3524
|
if (index < 0) {
|
|
@@ -3408,11 +3873,27 @@ const jsonImporter = Object.freeze({
|
|
|
3408
3873
|
const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);
|
|
3409
3874
|
const json = resolveJsonOptions(options);
|
|
3410
3875
|
const report = new ImportReportBuilder("json", resolved.errorLimit);
|
|
3411
|
-
const text = await
|
|
3876
|
+
const text = await readJsonText(input, report, resolved);
|
|
3412
3877
|
const { root, dialect } = documentOf(parseDocument(text, report), json, report);
|
|
3413
3878
|
readGraph(root, dialect, sink, report, resolved, json, options);
|
|
3414
3879
|
return report.finish();
|
|
3415
3880
|
},
|
|
3881
|
+
/**
|
|
3882
|
+
* List the graphs of a JSON document without importing them: each entry of a JGF or OBO
|
|
3883
|
+
* Graphs `graphs` array with its name (`id`, else its label) and node and edge counts; any
|
|
3884
|
+
* other document holds one graph.
|
|
3885
|
+
* @param input - the text, bytes or stream
|
|
3886
|
+
* @param options - format-specific and common options
|
|
3887
|
+
* @returns one listing per graph
|
|
3888
|
+
*/
|
|
3889
|
+
async listGraphs(input, options) {
|
|
3890
|
+
const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);
|
|
3891
|
+
const json = resolveJsonOptions(options);
|
|
3892
|
+
const report = new ImportReportBuilder("json", resolved.errorLimit);
|
|
3893
|
+
const text = await readJsonText(input, report, resolved);
|
|
3894
|
+
const { root, dialect } = documentOf(parseDocument(text, report), json, report);
|
|
3895
|
+
return listingsOf(root, dialect);
|
|
3896
|
+
},
|
|
3416
3897
|
/**
|
|
3417
3898
|
* Read every graph of a JSON document: each entry of a JGF `graphs` array into its own sink;
|
|
3418
3899
|
* any other document holds one graph.
|
|
@@ -3425,9 +3906,9 @@ const jsonImporter = Object.freeze({
|
|
|
3425
3906
|
const resolved = resolveImportOptions(options, FORMAT_DEFAULTS);
|
|
3426
3907
|
const json = resolveJsonOptions(options);
|
|
3427
3908
|
const first = new ImportReportBuilder("json", resolved.errorLimit);
|
|
3428
|
-
const text = await
|
|
3909
|
+
const text = await readJsonText(input, first, resolved);
|
|
3429
3910
|
const { root, dialect } = documentOf(parseDocument(text, first), json, first);
|
|
3430
|
-
const graphs =
|
|
3911
|
+
const graphs = listingsOf(root, dialect).length;
|
|
3431
3912
|
const reports = [];
|
|
3432
3913
|
for (let i = 0; i < Math.max(graphs, 1); i++) {
|
|
3433
3914
|
const report = i === 0 ? first : new ImportReportBuilder("json", resolved.errorLimit);
|
|
@@ -3439,7 +3920,7 @@ const jsonImporter = Object.freeze({
|
|
|
3439
3920
|
});
|
|
3440
3921
|
function readGraph(root, dialect, sink, report, resolved, json, options) {
|
|
3441
3922
|
const ctx = new ImportContext(sink, report, resolved, json, options?.defaultDirected !== void 0);
|
|
3442
|
-
reportSinkOptions(sink, options, report);
|
|
3923
|
+
reportSinkOptions(sink, options, report, dialect === "obographs");
|
|
3443
3924
|
reportUnusedOptions(options, report, USED_OPTIONS);
|
|
3444
3925
|
if (dialect === "cytoscape") {
|
|
3445
3926
|
importCytoscape(ctx, root);
|
|
@@ -3467,6 +3948,9 @@ function readGraph(root, dialect, sink, report, resolved, json, options) {
|
|
|
3467
3948
|
case "tree":
|
|
3468
3949
|
importTree(ctx, doc);
|
|
3469
3950
|
break;
|
|
3951
|
+
case "obographs":
|
|
3952
|
+
importObographs(ctx, doc);
|
|
3953
|
+
break;
|
|
3470
3954
|
default: {
|
|
3471
3955
|
const name = dialect;
|
|
3472
3956
|
throw new GraphFormatError("E_UNSUPPORTED", `unknown dialect ${name}`, {
|
|
@@ -3487,4 +3971,4 @@ export {
|
|
|
3487
3971
|
jsonCapabilities as j,
|
|
3488
3972
|
sniffJsonDialect as s
|
|
3489
3973
|
};
|
|
3490
|
-
//# sourceMappingURL=importer-
|
|
3974
|
+
//# sourceMappingURL=importer-Du5crN9l.js.map
|