@graphty/graph-io 0.3.30 → 0.3.31
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/dist/chunks/{choose-BfOLq6OX.js → choose-BJq_vp1b.js} +2 -2
- package/dist/chunks/{choose-BfOLq6OX.js.map → choose-BJq_vp1b.js.map} +1 -1
- package/dist/chunks/{constants-M8Qsjz1C.js → constants-Bw-6JQuC.js} +2 -2
- package/dist/chunks/{constants-M8Qsjz1C.js.map → constants-Bw-6JQuC.js.map} +1 -1
- package/dist/chunks/{escape-UMMpQZqs.js → escape-CnTfa_y8.js} +2 -2
- package/dist/chunks/{escape-UMMpQZqs.js.map → escape-CnTfa_y8.js.map} +1 -1
- package/dist/chunks/{export-Dq4U8Ubq.js → export-ZucVKiU4.js} +13 -3
- package/dist/chunks/{export-Dq4U8Ubq.js.map → export-ZucVKiU4.js.map} +1 -1
- package/dist/chunks/{exporter-BUosqV0K.js → exporter-BOLJIzvA.js} +5 -5
- package/dist/chunks/exporter-BOLJIzvA.js.map +1 -0
- package/dist/chunks/{exporter-Bd_VZ9ph.js → exporter-DRNkA2k0.js} +5 -5
- package/dist/chunks/{exporter-Bd_VZ9ph.js.map → exporter-DRNkA2k0.js.map} +1 -1
- package/dist/chunks/{exporter-DEk_XLLs.js → exporter-DgDjwLOm.js} +7 -8
- package/dist/chunks/exporter-DgDjwLOm.js.map +1 -0
- package/dist/chunks/{exporter-COgVm-ff.js → exporter-hc2ZuqVe.js} +4 -4
- package/dist/chunks/{exporter-COgVm-ff.js.map → exporter-hc2ZuqVe.js.map} +1 -1
- package/dist/chunks/{importer-Cj4-lXlv.js → importer-BAlFKpHP.js} +6 -6
- package/dist/chunks/{importer-Cj4-lXlv.js.map → importer-BAlFKpHP.js.map} +1 -1
- package/dist/chunks/{importer-AQ3KpNHz.js → importer-ByCd2CAY.js} +5 -5
- package/dist/chunks/{importer-AQ3KpNHz.js.map → importer-ByCd2CAY.js.map} +1 -1
- package/dist/chunks/{importer-DwSZvMDq.js → importer-CaLIrkjL.js} +5 -5
- package/dist/chunks/{importer-DwSZvMDq.js.map → importer-CaLIrkjL.js.map} +1 -1
- package/dist/chunks/{importer-CV8au8gH.js → importer-D7xB8oVV.js} +4 -4
- package/dist/chunks/{importer-CV8au8gH.js.map → importer-D7xB8oVV.js.map} +1 -1
- package/dist/chunks/{importer-BsZa2Phx.js → importer-DsNj_zoG.js} +3 -3
- package/dist/chunks/{importer-BsZa2Phx.js.map → importer-DsNj_zoG.js.map} +1 -1
- package/dist/chunks/{importer-Dkn79TjB.js → importer-WPz-AUz8.js} +4 -4
- package/dist/chunks/{importer-Dkn79TjB.js.map → importer-WPz-AUz8.js.map} +1 -1
- package/dist/chunks/{importer-DQsgmhxc.js → importer-rjFCmKfx.js} +4 -4
- package/dist/chunks/{importer-DQsgmhxc.js.map → importer-rjFCmKfx.js.map} +1 -1
- package/dist/chunks/{json-elements-CreeKoaH.js → json-elements-CkC87El2.js} +3 -3
- package/dist/chunks/{json-elements-CreeKoaH.js.map → json-elements-CkC87El2.js.map} +1 -1
- package/dist/chunks/{ontology-export-C5Xd3W-7.js → ontology-export-BRErBO6J.js} +11 -9
- package/dist/chunks/ontology-export-BRErBO6J.js.map +1 -0
- package/dist/chunks/{records-BwaH_2ll.js → records-DwfSjH8c.js} +2 -2
- package/dist/chunks/{records-BwaH_2ll.js.map → records-DwfSjH8c.js.map} +1 -1
- package/dist/chunks/{text-4HHe6YH3.js → text-BEEWD-G1.js} +2 -2
- package/dist/chunks/{text-4HHe6YH3.js.map → text-BEEWD-G1.js.map} +1 -1
- package/dist/csv.js +4 -4
- package/dist/cx.js +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +1 -1
- package/dist/gexf.js +2 -2
- package/dist/gml.js +3 -3
- package/dist/graph-io.js +26 -26
- package/dist/graphml.js +2 -2
- package/dist/json.js +1 -1
- package/dist/neo4j.js +3 -3
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/src/common/export.d.ts +6 -1
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +18 -2
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/ontology-export.d.ts.map +1 -1
- package/dist/src/common/ontology-export.js +11 -15
- package/dist/src/common/ontology-export.js.map +1 -1
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +2 -4
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/obo/exporter.d.ts +2 -2
- package/dist/src/formats/obo/exporter.js +2 -2
- package/dist/xgmml.js +2 -2
- package/package.json +2 -2
- package/src/common/export.ts +25 -3
- package/src/common/ontology-export.ts +12 -17
- package/src/formats/cx2/exporter.ts +2 -4
- package/src/formats/obo/exporter.ts +2 -2
- package/dist/chunks/exporter-BUosqV0K.js.map +0 -1
- package/dist/chunks/exporter-DEk_XLLs.js.map +0 -1
- package/dist/chunks/ontology-export-C5Xd3W-7.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphty/graph-io",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.31",
|
|
4
4
|
"description": "Read and write 13 graph file formats (JSON, GraphML, GEXF, CSV, GML, DOT, Pajek, Neo4j CSV, XGMML, CX2, CX, OBO, Cytoscape sessions) as @graphty/graph-format snapshots",
|
|
5
5
|
"author": "Adam Powers <apowers@ato.ms>",
|
|
6
6
|
"type": "module",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
},
|
|
122
122
|
"homepage": "https://graphty.app/docs/graph-io/",
|
|
123
123
|
"dependencies": {
|
|
124
|
-
"@graphty/graph-format": "^1.3.
|
|
124
|
+
"@graphty/graph-format": "^1.3.9"
|
|
125
125
|
},
|
|
126
126
|
"peerDependencies": {
|
|
127
127
|
"@graphty/graph-format": "^1.0.0"
|
package/src/common/export.ts
CHANGED
|
@@ -293,9 +293,14 @@ export interface CheckExtras {
|
|
|
293
293
|
/**
|
|
294
294
|
* Roles the format writes into a fixed slot whose importer reads them back under a fixed name;
|
|
295
295
|
* a role column named otherwise is reported as W_COLUMN_NAME_CHANGED (role -> the name the
|
|
296
|
-
* importer gives it). Defaults to none.
|
|
296
|
+
* importer gives it). Defaults to none. `nodeRoleNames` and `edgeRoleNames` override it for one
|
|
297
|
+
* kind, for a format whose slot exists for nodes only (or edges only).
|
|
297
298
|
*/
|
|
298
299
|
readonly roleNames?: Readonly<Record<string, string>> | undefined;
|
|
300
|
+
/** Like `roleNames`, for node columns only. */
|
|
301
|
+
readonly nodeRoleNames?: Readonly<Record<string, string>> | undefined;
|
|
302
|
+
/** Like `roleNames`, for edge columns only: `{}` for a format with no edge slot for any role. */
|
|
303
|
+
readonly edgeRoleNames?: Readonly<Record<string, string>> | undefined;
|
|
299
304
|
/**
|
|
300
305
|
* False for a format that writes no node or edge attributes except the ones whose role is in
|
|
301
306
|
* `roles`: every other attribute column is reported once as W_COLUMN_DROPPED, instead of the
|
|
@@ -555,6 +560,22 @@ function charsetText(charset: ExportCapabilities["idCharset"], n: number): strin
|
|
|
555
560
|
}
|
|
556
561
|
}
|
|
557
562
|
|
|
563
|
+
/**
|
|
564
|
+
* The role names of one kind (CheckExtras.nodeRoleNames / edgeRoleNames, else roleNames).
|
|
565
|
+
* @param domain - "node", "edge" or "graph"
|
|
566
|
+
* @param extras - format extras
|
|
567
|
+
* @returns the role names, or undefined when the extras name none
|
|
568
|
+
*/
|
|
569
|
+
function roleNamesOf(domain: string, extras: CheckExtras): Readonly<Record<string, string>> | undefined {
|
|
570
|
+
if (domain === "node") {
|
|
571
|
+
return extras.nodeRoleNames ?? extras.roleNames;
|
|
572
|
+
}
|
|
573
|
+
if (domain === "edge") {
|
|
574
|
+
return extras.edgeRoleNames ?? extras.roleNames;
|
|
575
|
+
}
|
|
576
|
+
return extras.roleNames;
|
|
577
|
+
}
|
|
578
|
+
|
|
558
579
|
/**
|
|
559
580
|
* Whether a format writes the attributes of one kind (CheckExtras.nodeAttributes / edgeAttributes, else attributes).
|
|
560
581
|
* @param domain - "node", "edge" or "graph"
|
|
@@ -622,8 +643,9 @@ function checkColumns(
|
|
|
622
643
|
continue;
|
|
623
644
|
}
|
|
624
645
|
const label = `${domain} column "${name}"`;
|
|
625
|
-
|
|
626
|
-
|
|
646
|
+
const roleNames = roleNamesOf(domain, extras);
|
|
647
|
+
if (role !== null && roleNames !== undefined) {
|
|
648
|
+
const fixed = roleNames[role];
|
|
627
649
|
if (fixed !== undefined && fixed !== name) {
|
|
628
650
|
note(
|
|
629
651
|
LOSS.COLUMN_NAME_CHANGED,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import { type Column, GraphFormatError, type GraphSnapshot } from "@graphty/graph-format";
|
|
10
10
|
|
|
11
|
-
import { type ExportCapabilities
|
|
11
|
+
import { type ExportCapabilities } from "../types.js";
|
|
12
12
|
import { COLUMN_AS_PROPERTY_VALUE_CODE, ROLE_ASSUMED_CODE } from "./codes.js";
|
|
13
13
|
import { checkCapabilities, LOSS } from "./export.js";
|
|
14
14
|
import { formatNumber } from "./format.js";
|
|
@@ -32,7 +32,8 @@ const SUPERSEDED: ReadonlySet<string> = new Set([
|
|
|
32
32
|
|
|
33
33
|
/** The roles the ontology formats have a slot for, and the column names their importers give them. */
|
|
34
34
|
const SLOT_ROLES: ReadonlySet<string> = new Set(["label", "kind"]);
|
|
35
|
-
const
|
|
35
|
+
const NODE_ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({ label: "name" });
|
|
36
|
+
const EDGE_ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({ kind: "relation" });
|
|
36
37
|
|
|
37
38
|
/**
|
|
38
39
|
* The roles whose columns are never written as values (their loss notes come from checkCapabilities()).
|
|
@@ -335,8 +336,15 @@ export function capabilityNotes(
|
|
|
335
336
|
const { label, note } = spec;
|
|
336
337
|
let fatal: GraphFormatError | null = null;
|
|
337
338
|
const kind = snapshot.edges.byRole("kind");
|
|
338
|
-
|
|
339
|
-
|
|
339
|
+
// a node label goes into the name slot and an edge kind into the relation slot, when written there;
|
|
340
|
+
// an edge label has no slot (it becomes edge qualifiers or metadata), so it is never renamed
|
|
341
|
+
const extras = {
|
|
342
|
+
roles: SLOT_ROLES,
|
|
343
|
+
nodeRoleNames: label === null ? {} : NODE_ROLE_NAMES,
|
|
344
|
+
edgeRoleNames: kind !== null && isText(kind) ? EDGE_ROLE_NAMES : {},
|
|
345
|
+
};
|
|
346
|
+
for (const gen of checkCapabilities(snapshot, spec.caps, common, extras)) {
|
|
347
|
+
if (SUPERSEDED.has(gen.code)) {
|
|
340
348
|
continue;
|
|
341
349
|
}
|
|
342
350
|
if (gen.code === LOSS.MIXED_DIRECTION_ERROR && fatal === null) {
|
|
@@ -384,19 +392,6 @@ function slotlessRoleNotes(snapshot: GraphSnapshot, spec: CapabilityNoteSpec): v
|
|
|
384
392
|
}
|
|
385
393
|
}
|
|
386
394
|
|
|
387
|
-
/**
|
|
388
|
-
* Whether a name-change note is about a column written into its slot: the node label, or a text
|
|
389
|
-
* edge kind column.
|
|
390
|
-
* @param gen - the note
|
|
391
|
-
* @param label - the node label column, or null
|
|
392
|
-
* @param kind - the edge kind column, or null
|
|
393
|
-
* @returns true when it is
|
|
394
|
-
*/
|
|
395
|
-
function isSlotRename(gen: LossNote, label: Column | null, kind: Column | null): boolean {
|
|
396
|
-
const isLabel = label !== null && gen.column === label.meta.name;
|
|
397
|
-
return isLabel || (kind !== null && gen.column === kind.meta.name && isText(kind));
|
|
398
|
-
}
|
|
399
|
-
|
|
400
395
|
/**
|
|
401
396
|
* Record the columns that read back absent: a node or edge column without a set cell on a written
|
|
402
397
|
* element (the importers declare a column when a value needs it).
|
|
@@ -297,6 +297,8 @@ function capabilityNotes(
|
|
|
297
297
|
for (const gen of checkCapabilities(snapshot, CX2_CAPABILITIES, common, {
|
|
298
298
|
roles: SLOT_ROLES,
|
|
299
299
|
roleNames: ROLE_NAMES,
|
|
300
|
+
// only the node label is written into the "n" slot; an edge label keeps its own name
|
|
301
|
+
edgeRoleNames: {},
|
|
300
302
|
})) {
|
|
301
303
|
if (!keepGenericNote(gen, bypassNames)) {
|
|
302
304
|
continue;
|
|
@@ -337,10 +339,6 @@ function keepGenericNote(gen: LossNote, bypassNames: ReadonlySet<string>): boole
|
|
|
337
339
|
if (gen.column !== null && bypassNames.has(gen.column) && (gen.code === LOSS.JSON || gen.code === LOSS.DTYPE)) {
|
|
338
340
|
return false;
|
|
339
341
|
}
|
|
340
|
-
if (gen.code === LOSS.COLUMN_NAME_CHANGED && gen.message.startsWith("edge column")) {
|
|
341
|
-
// only the node label is written into the "n" slot; an edge label keeps its own name
|
|
342
|
-
return false;
|
|
343
|
-
}
|
|
344
342
|
// ids are counted by planNodeIds(): CX2 also keeps integer ids beyond 2^53, which the generic rule refuses
|
|
345
343
|
return gen.code !== LOSS.ID_CHARSET && gen.code !== LOSS.ID_MANGLED;
|
|
346
344
|
}
|
|
@@ -150,8 +150,8 @@ export const OBO_LOSS = Object.freeze({
|
|
|
150
150
|
*/
|
|
151
151
|
ROLE_ASSUMED: ROLE_ASSUMED_CODE,
|
|
152
152
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
153
|
+
* The node label column is written as each node's `name` and reads back as the column `name`. An edge label has no slot:
|
|
154
|
+
* it is written as a qualifier (W_ROLE_DROPPED and W_OBO_EDGE_COLUMN_AS_QUALIFIER), never under a new name.
|
|
155
155
|
*/
|
|
156
156
|
COLUMN_NAME_CHANGED: LOSS.COLUMN_NAME_CHANGED,
|
|
157
157
|
/**
|