@graphty/graph-io 0.3.38 → 0.3.39
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-CsO24U-5.js → choose-CS3fvGT1.js} +2 -2
- package/dist/chunks/{choose-CsO24U-5.js.map → choose-CS3fvGT1.js.map} +1 -1
- package/dist/chunks/{constants-BPRiVyBu.js → constants-DqKZT6cH.js} +2 -2
- package/dist/chunks/{constants-BPRiVyBu.js.map → constants-DqKZT6cH.js.map} +1 -1
- package/dist/chunks/{escape-BRcyzD77.js → escape-BpYMQZVa.js} +2 -2
- package/dist/chunks/{escape-BRcyzD77.js.map → escape-BpYMQZVa.js.map} +1 -1
- package/dist/chunks/{export-CTUlibzr.js → export-B-aVCwyG.js} +103 -92
- package/dist/chunks/export-B-aVCwyG.js.map +1 -0
- package/dist/chunks/{exporter-Bf5tZA0X.js → exporter-BqKs1Q12.js} +4 -4
- package/dist/chunks/{exporter-Bf5tZA0X.js.map → exporter-BqKs1Q12.js.map} +1 -1
- package/dist/chunks/{exporter-D-qQuRcG.js → exporter-CNJZF_BN.js} +6 -6
- package/dist/chunks/exporter-CNJZF_BN.js.map +1 -0
- package/dist/chunks/{exporter-Bn4jdYfd.js → exporter-DXqCPNrI.js} +4 -4
- package/dist/chunks/{exporter-Bn4jdYfd.js.map → exporter-DXqCPNrI.js.map} +1 -1
- package/dist/chunks/{exporter-F0vT919P.js → exporter-SFYkDzD0.js} +5 -4
- package/dist/chunks/exporter-SFYkDzD0.js.map +1 -0
- package/dist/chunks/{importer-oIUx9u_g.js → importer--tQQsY4W.js} +40 -18
- package/dist/chunks/importer--tQQsY4W.js.map +1 -0
- package/dist/chunks/{importer-yWUPR_nU.js → importer-B7Ir269L.js} +4 -4
- package/dist/chunks/{importer-yWUPR_nU.js.map → importer-B7Ir269L.js.map} +1 -1
- package/dist/chunks/{importer-BuzbaFFY.js → importer-BfJ1jnNr.js} +3 -3
- package/dist/chunks/{importer-BuzbaFFY.js.map → importer-BfJ1jnNr.js.map} +1 -1
- package/dist/chunks/{importer-CEuUmyPe.js → importer-CSt-gaYE.js} +6 -6
- package/dist/chunks/{importer-CEuUmyPe.js.map → importer-CSt-gaYE.js.map} +1 -1
- package/dist/chunks/{importer-Bgb9sgZZ.js → importer-CqgYq4Ld.js} +6 -8
- package/dist/chunks/importer-CqgYq4Ld.js.map +1 -0
- package/dist/chunks/{importer-CNMQnHDd.js → importer-DvFznt5-.js} +4 -4
- package/dist/chunks/{importer-CNMQnHDd.js.map → importer-DvFznt5-.js.map} +1 -1
- package/dist/chunks/{importer-DqMtyYLX.js → importer-PVXkeoaS.js} +6 -8
- package/dist/chunks/importer-PVXkeoaS.js.map +1 -0
- package/dist/chunks/{json-elements-AkglPS3m.js → json-elements-CXs4z1iL.js} +3 -3
- package/dist/chunks/{json-elements-AkglPS3m.js.map → json-elements-CXs4z1iL.js.map} +1 -1
- package/dist/chunks/{ontology-export-DDoG3egY.js → ontology-export-50L9DOV4.js} +2 -2
- package/dist/chunks/{ontology-export-DDoG3egY.js.map → ontology-export-50L9DOV4.js.map} +1 -1
- package/dist/chunks/{records-ChmWZGuz.js → records-C9jd7yLD.js} +2 -2
- package/dist/chunks/{records-ChmWZGuz.js.map → records-C9jd7yLD.js.map} +1 -1
- package/dist/chunks/{text-Btw3sBe_.js → text-Bjfa1xYL.js} +2 -2
- package/dist/chunks/{text-Btw3sBe_.js.map → text-Bjfa1xYL.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 +8 -6
- package/dist/gml.js.map +1 -1
- 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/direction.js +1 -1
- package/dist/src/common/direction.js.map +1 -1
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +136 -71
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/input.js +1 -1
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts +6 -0
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +11 -6
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/names.d.ts +5 -0
- package/dist/src/formats/dot/names.d.ts.map +1 -1
- package/dist/src/formats/dot/names.js +5 -0
- package/dist/src/formats/dot/names.js.map +1 -1
- package/dist/src/formats/dot/tokenizer.js +9 -9
- package/dist/src/formats/dot/tokenizer.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts +6 -0
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +6 -3
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/graphml/importer.d.ts.map +1 -1
- package/dist/src/formats/graphml/importer.js +2 -4
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/obo/importer.d.ts.map +1 -1
- package/dist/src/formats/obo/importer.js +2 -1
- package/dist/src/formats/obo/importer.js.map +1 -1
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +4 -5
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/sniff.js +1 -1
- package/dist/src/sniff.js.map +1 -1
- package/dist/xgmml.js +2 -2
- package/package.json +2 -2
- package/src/common/direction.ts +1 -1
- package/src/common/export.ts +190 -97
- package/src/common/input.ts +1 -1
- package/src/formats/dot/importer.ts +35 -4
- package/src/formats/dot/names.ts +6 -0
- package/src/formats/dot/tokenizer.ts +9 -9
- package/src/formats/gml/importer.ts +14 -3
- package/src/formats/graphml/importer.ts +2 -4
- package/src/formats/obo/importer.ts +2 -1
- package/src/formats/pajek/exporter.ts +6 -4
- package/src/sniff.ts +1 -1
- package/dist/chunks/export-CTUlibzr.js.map +0 -1
- package/dist/chunks/exporter-D-qQuRcG.js.map +0 -1
- package/dist/chunks/exporter-F0vT919P.js.map +0 -1
- package/dist/chunks/importer-Bgb9sgZZ.js.map +0 -1
- package/dist/chunks/importer-DqMtyYLX.js.map +0 -1
- package/dist/chunks/importer-oIUx9u_g.js.map +0 -1
|
@@ -97,6 +97,7 @@ import {
|
|
|
97
97
|
PARENT_COLUMN,
|
|
98
98
|
PIN_ATTRIBUTE,
|
|
99
99
|
POS_ATTRIBUTE,
|
|
100
|
+
POSITION_COLUMN,
|
|
100
101
|
SOURCE_PORT_COLUMN,
|
|
101
102
|
TARGET_PORT_COLUMN,
|
|
102
103
|
} from "./names.js";
|
|
@@ -122,6 +123,12 @@ export interface DotImportOptions extends GraphChoiceOptions, CommonImportOption
|
|
|
122
123
|
* @defaultValue true
|
|
123
124
|
*/
|
|
124
125
|
positions?: boolean | undefined;
|
|
126
|
+
/**
|
|
127
|
+
* With `positions`, also keep `pos` as the text the file wrote; the position column is then
|
|
128
|
+
* named `graphty.position`, so a reader gets both.
|
|
129
|
+
* @defaultValue false
|
|
130
|
+
*/
|
|
131
|
+
keepPositionSource?: boolean | undefined;
|
|
125
132
|
}
|
|
126
133
|
|
|
127
134
|
/**
|
|
@@ -323,7 +330,7 @@ interface Scope {
|
|
|
323
330
|
*/
|
|
324
331
|
export const dotImporter: GraphImporter<DotImportOptions> = Object.freeze({
|
|
325
332
|
format: DOT_FORMAT,
|
|
326
|
-
options: Object.freeze(["mismatchedEdgeOperator", "positions"]),
|
|
333
|
+
options: Object.freeze(["keepPositionSource", "mismatchedEdgeOperator", "positions"]),
|
|
327
334
|
extensions: EXTENSIONS,
|
|
328
335
|
mimeTypes: MIME_TYPES,
|
|
329
336
|
|
|
@@ -376,7 +383,15 @@ export const dotImporter: GraphImporter<DotImportOptions> = Object.freeze({
|
|
|
376
383
|
const reports = { current: report };
|
|
377
384
|
const lexer = dotLexer(text, reports);
|
|
378
385
|
const first = guard(report, () => lexer.next());
|
|
379
|
-
const parser = new DotParser(
|
|
386
|
+
const parser = new DotParser(
|
|
387
|
+
lexer,
|
|
388
|
+
sink,
|
|
389
|
+
report,
|
|
390
|
+
resolved,
|
|
391
|
+
mismatch,
|
|
392
|
+
options?.positions !== false,
|
|
393
|
+
options?.keepPositionSource === true,
|
|
394
|
+
);
|
|
380
395
|
parser.headCharset = head.charset;
|
|
381
396
|
const trailing = parseGraph(parser, report, first);
|
|
382
397
|
if (trailing.kind !== "eof") {
|
|
@@ -429,7 +444,15 @@ export const dotImporter: GraphImporter<DotImportOptions> = Object.freeze({
|
|
|
429
444
|
reports.current = report;
|
|
430
445
|
const sink = sinkFor(done.length);
|
|
431
446
|
reportSinkOptions(sink, options, report);
|
|
432
|
-
const parser = new DotParser(
|
|
447
|
+
const parser = new DotParser(
|
|
448
|
+
lexer,
|
|
449
|
+
sink,
|
|
450
|
+
report,
|
|
451
|
+
resolved,
|
|
452
|
+
mismatch,
|
|
453
|
+
options?.positions !== false,
|
|
454
|
+
options?.keepPositionSource === true,
|
|
455
|
+
);
|
|
433
456
|
parser.headCharset = head.charset;
|
|
434
457
|
token = parseGraph(parser, report, token);
|
|
435
458
|
throwIfAborted(resolved.signal);
|
|
@@ -686,6 +709,8 @@ class DotParser {
|
|
|
686
709
|
private readonly mismatch: "operator" | "header" | "error";
|
|
687
710
|
private readonly positions: boolean;
|
|
688
711
|
|
|
712
|
+
private readonly keepPositionSource: boolean;
|
|
713
|
+
|
|
689
714
|
private readonly ids: IdCoercer;
|
|
690
715
|
|
|
691
716
|
private readonly resolver: DirectionResolver;
|
|
@@ -758,6 +783,7 @@ class DotParser {
|
|
|
758
783
|
* @param options - the resolved common options
|
|
759
784
|
* @param mismatch - the resolved mismatchedEdgeOperator option
|
|
760
785
|
* @param positions - whether `pos` goes to the position column
|
|
786
|
+
* @param keepPositionSource - whether `pos` also stays as text
|
|
761
787
|
*/
|
|
762
788
|
constructor(
|
|
763
789
|
lexer: DotTokenizer,
|
|
@@ -766,6 +792,7 @@ class DotParser {
|
|
|
766
792
|
options: ResolvedImportOptions,
|
|
767
793
|
mismatch: "operator" | "header" | "error",
|
|
768
794
|
positions: boolean,
|
|
795
|
+
keepPositionSource: boolean,
|
|
769
796
|
) {
|
|
770
797
|
this.lexer = lexer;
|
|
771
798
|
this.sink = sink;
|
|
@@ -773,6 +800,7 @@ class DotParser {
|
|
|
773
800
|
this.options = options;
|
|
774
801
|
this.mismatch = mismatch;
|
|
775
802
|
this.positions = positions;
|
|
803
|
+
this.keepPositionSource = keepPositionSource;
|
|
776
804
|
this.ids = new IdCoercer(options.ids);
|
|
777
805
|
this.resolver = new DirectionResolver(sink, report, options.onMixedDirection);
|
|
778
806
|
}
|
|
@@ -1586,6 +1614,9 @@ class DotParser {
|
|
|
1586
1614
|
this.sink.setNodeValue(this.nodeLabel(), index, value);
|
|
1587
1615
|
} else if (name === POS_ATTRIBUTE && this.positions) {
|
|
1588
1616
|
this.setPosition(index, value, line, element);
|
|
1617
|
+
if (this.keepPositionSource) {
|
|
1618
|
+
this.textWriter("node", name).write(index, value);
|
|
1619
|
+
}
|
|
1589
1620
|
} else {
|
|
1590
1621
|
this.textWriter("node", name).write(index, value);
|
|
1591
1622
|
}
|
|
@@ -1766,7 +1797,7 @@ class DotParser {
|
|
|
1766
1797
|
private positionColumn(dims: 2 | 3): ColumnHandle {
|
|
1767
1798
|
if (this.positionHandle === INVALID_INDEX) {
|
|
1768
1799
|
this.positionHandle = this.declare("node", {
|
|
1769
|
-
name: POS_ATTRIBUTE,
|
|
1800
|
+
name: this.keepPositionSource ? POSITION_COLUMN : POS_ATTRIBUTE,
|
|
1770
1801
|
dtype: "f64",
|
|
1771
1802
|
components: 3,
|
|
1772
1803
|
nullable: true,
|
package/src/formats/dot/names.ts
CHANGED
|
@@ -54,6 +54,12 @@ export const LABEL_ATTRIBUTE = "label";
|
|
|
54
54
|
*/
|
|
55
55
|
export const POS_ATTRIBUTE = "pos";
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* The node position column when the import keeps `pos` as text too (the `keepPositionSource` option).
|
|
59
|
+
* @category Plugin helpers
|
|
60
|
+
*/
|
|
61
|
+
export const POSITION_COLUMN = "graphty.position";
|
|
62
|
+
|
|
57
63
|
/**
|
|
58
64
|
* The edge attribute cgraph uses as an edge's identity within its endpoints, mapped to the edge id role.
|
|
59
65
|
* @category Plugin helpers
|
|
@@ -148,15 +148,15 @@ export class DotTokenizer {
|
|
|
148
148
|
const { line } = this;
|
|
149
149
|
const c = text.charCodeAt(start);
|
|
150
150
|
switch (c) {
|
|
151
|
-
case 0x7b: // {
|
|
152
|
-
case 0x7d: // }
|
|
153
|
-
case 0x5b: // [
|
|
154
|
-
case 0x5d: // ]
|
|
155
|
-
case 0x3b: // ;
|
|
156
|
-
case 0x2c: // ,
|
|
157
|
-
case 0x3d: // =
|
|
158
|
-
case 0x3a: // :
|
|
159
|
-
case 0x2b: // +
|
|
151
|
+
case 0x7b: // "{"
|
|
152
|
+
case 0x7d: // "}"
|
|
153
|
+
case 0x5b: // "["
|
|
154
|
+
case 0x5d: // "]"
|
|
155
|
+
case 0x3b: // ";"
|
|
156
|
+
case 0x2c: // ","
|
|
157
|
+
case 0x3d: // "="
|
|
158
|
+
case 0x3a: // ":"
|
|
159
|
+
case 0x2b: // "+"
|
|
160
160
|
this.pos++;
|
|
161
161
|
return { kind: "punct", text: text[start], quoted: false, html: false, line };
|
|
162
162
|
case 0x2d: {
|
|
@@ -97,6 +97,12 @@ export interface GmlImportOptions extends GraphChoiceOptions, CommonImportOption
|
|
|
97
97
|
* @defaultValue true
|
|
98
98
|
*/
|
|
99
99
|
positions?: boolean | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* With `positions`, also keep the whole `graphics` record, x / y / z included, as the JSON
|
|
102
|
+
* attribute named `graphics`, so a reader gets both the position and the record as written.
|
|
103
|
+
* @defaultValue false
|
|
104
|
+
*/
|
|
105
|
+
keepPositionSource?: boolean | undefined;
|
|
100
106
|
/**
|
|
101
107
|
* Store a text attribute whose values repeat a lot (fewer distinct values than half the rows)
|
|
102
108
|
* as a dictionary column, which uses less memory and reads the same. Such a column reports
|
|
@@ -378,6 +384,8 @@ class GmlImport {
|
|
|
378
384
|
|
|
379
385
|
private readonly positions: boolean;
|
|
380
386
|
|
|
387
|
+
private readonly keepPositionSource: boolean;
|
|
388
|
+
|
|
381
389
|
private readonly dictionaries: boolean;
|
|
382
390
|
|
|
383
391
|
private readonly coercer: IdCoercer;
|
|
@@ -470,6 +478,7 @@ class GmlImport {
|
|
|
470
478
|
this.report = report;
|
|
471
479
|
this.options = options;
|
|
472
480
|
this.positions = format?.positions ?? true;
|
|
481
|
+
this.keepPositionSource = format?.keepPositionSource ?? false;
|
|
473
482
|
this.dictionaries = format?.dictionaries ?? true;
|
|
474
483
|
this.coercer = new IdCoercer(options.ids);
|
|
475
484
|
}
|
|
@@ -755,7 +764,8 @@ class GmlImport {
|
|
|
755
764
|
}
|
|
756
765
|
const positioned = x && y;
|
|
757
766
|
entry.position ||= positioned;
|
|
758
|
-
|
|
767
|
+
// with keepPositionSource the whole record, x / y / z included, goes to the json column too
|
|
768
|
+
entry.rest ||= positioned ? other || this.keepPositionSource : true;
|
|
759
769
|
}
|
|
760
770
|
|
|
761
771
|
// ============================================================ pass 2: the push
|
|
@@ -1541,7 +1551,8 @@ class GmlImport {
|
|
|
1541
1551
|
const positionPlan = plan.position;
|
|
1542
1552
|
let rest: unknown = first;
|
|
1543
1553
|
if (isRecord(first) && positionPlan !== null) {
|
|
1544
|
-
|
|
1554
|
+
const left = this.writePosition(positionPlan, index, this.keepPositionSource ? { ...first } : first, where);
|
|
1555
|
+
rest = this.keepPositionSource ? first : left;
|
|
1545
1556
|
} else if (!isRecord(first)) {
|
|
1546
1557
|
this.graphicsWarning("scalar", `node ${where.element}'s graphics is not a record`, where);
|
|
1547
1558
|
}
|
|
@@ -1924,7 +1935,7 @@ function sniffGml(head: Uint8Array): number {
|
|
|
1924
1935
|
*/
|
|
1925
1936
|
export const gmlImporter: GraphImporter<GmlImportOptions> = Object.freeze({
|
|
1926
1937
|
format: "gml",
|
|
1927
|
-
options: Object.freeze(["dictionaries", "positions"]),
|
|
1938
|
+
options: Object.freeze(["dictionaries", "keepPositionSource", "positions"]),
|
|
1928
1939
|
extensions: Object.freeze([".gml"]),
|
|
1929
1940
|
mimeTypes: Object.freeze(["text/x-gml", "text/plain"]),
|
|
1930
1941
|
sniff: sniffGml,
|
|
@@ -512,16 +512,14 @@ class GraphmlReader implements XmlHandler {
|
|
|
512
512
|
const parent = this.ctx.at(-1) ?? null;
|
|
513
513
|
switch (parent) {
|
|
514
514
|
case Ctx.Capture:
|
|
515
|
+
case Ctx.Data:
|
|
516
|
+
case Ctx.Default:
|
|
515
517
|
this.captureStart(name, attrs);
|
|
516
518
|
return;
|
|
517
519
|
case Ctx.Skip:
|
|
518
520
|
case Ctx.Desc:
|
|
519
521
|
this.ctx.push(Ctx.Skip);
|
|
520
522
|
return;
|
|
521
|
-
case Ctx.Data:
|
|
522
|
-
case Ctx.Default:
|
|
523
|
-
this.captureStart(name, attrs);
|
|
524
|
-
return;
|
|
525
523
|
case Ctx.Dropped:
|
|
526
524
|
this.dropStart(localName(name));
|
|
527
525
|
return;
|
|
@@ -1429,7 +1429,8 @@ class OboReader {
|
|
|
1429
1429
|
return;
|
|
1430
1430
|
}
|
|
1431
1431
|
const map = (record.values.get("obo.qualifiers") as Record<string, unknown[]> | undefined) ?? {};
|
|
1432
|
-
|
|
1432
|
+
map[tag] ??= [];
|
|
1433
|
+
map[tag].push({ value, qualifiers });
|
|
1433
1434
|
record.values.set("obo.qualifiers", map);
|
|
1434
1435
|
}
|
|
1435
1436
|
|
|
@@ -979,10 +979,12 @@ export const pajekExporter: GraphExporter<PajekExportOptions> = Object.freeze({
|
|
|
979
979
|
// keyword and the relation name (dict columns written as keywords)
|
|
980
980
|
const owned = new Set<string>();
|
|
981
981
|
for (const { column, slot } of [...nodePlan, ...edgePlan]) {
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
982
|
+
// a shape written as a parameter is owned too: its note already says the column reads back as string
|
|
983
|
+
if (
|
|
984
|
+
slot === "shape" ||
|
|
985
|
+
slot === "relation" ||
|
|
986
|
+
(slot === "param" && column.meta.domain === "node" && column.meta.name === SHAPE_COLUMN)
|
|
987
|
+
) {
|
|
986
988
|
owned.add(`${column.meta.domain}:${column.meta.name}`);
|
|
987
989
|
}
|
|
988
990
|
}
|
package/src/sniff.ts
CHANGED