@faubulous/mentor-rdf-serializers 1.0.0

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.
Files changed (82) hide show
  1. package/README.md +582 -0
  2. package/dist/base-serializer.d.ts +63 -0
  3. package/dist/base-serializer.d.ts.map +1 -0
  4. package/dist/base-serializer.js +144 -0
  5. package/dist/base-serializer.js.map +1 -0
  6. package/dist/base-token-formatter.d.ts +225 -0
  7. package/dist/base-token-formatter.d.ts.map +1 -0
  8. package/dist/base-token-formatter.js +521 -0
  9. package/dist/base-token-formatter.js.map +1 -0
  10. package/dist/index.d.ts +20 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +36 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/jsonld/serializer.d.ts +99 -0
  15. package/dist/jsonld/serializer.d.ts.map +1 -0
  16. package/dist/jsonld/serializer.js +282 -0
  17. package/dist/jsonld/serializer.js.map +1 -0
  18. package/dist/n3/formatter.d.ts +105 -0
  19. package/dist/n3/formatter.d.ts.map +1 -0
  20. package/dist/n3/formatter.js +444 -0
  21. package/dist/n3/formatter.js.map +1 -0
  22. package/dist/n3/serializer.d.ts +103 -0
  23. package/dist/n3/serializer.d.ts.map +1 -0
  24. package/dist/n3/serializer.js +134 -0
  25. package/dist/n3/serializer.js.map +1 -0
  26. package/dist/nquads/formatter.d.ts +44 -0
  27. package/dist/nquads/formatter.d.ts.map +1 -0
  28. package/dist/nquads/formatter.js +116 -0
  29. package/dist/nquads/formatter.js.map +1 -0
  30. package/dist/nquads/serializer.d.ts +38 -0
  31. package/dist/nquads/serializer.d.ts.map +1 -0
  32. package/dist/nquads/serializer.js +70 -0
  33. package/dist/nquads/serializer.js.map +1 -0
  34. package/dist/ntriples/formatter.d.ts +44 -0
  35. package/dist/ntriples/formatter.d.ts.map +1 -0
  36. package/dist/ntriples/formatter.js +116 -0
  37. package/dist/ntriples/formatter.js.map +1 -0
  38. package/dist/ntriples/serializer.d.ts +38 -0
  39. package/dist/ntriples/serializer.d.ts.map +1 -0
  40. package/dist/ntriples/serializer.js +79 -0
  41. package/dist/ntriples/serializer.js.map +1 -0
  42. package/dist/sorting/index.d.ts +5 -0
  43. package/dist/sorting/index.d.ts.map +1 -0
  44. package/dist/sorting/index.js +5 -0
  45. package/dist/sorting/index.js.map +1 -0
  46. package/dist/sorting/strategies.d.ts +46 -0
  47. package/dist/sorting/strategies.d.ts.map +1 -0
  48. package/dist/sorting/strategies.js +259 -0
  49. package/dist/sorting/strategies.js.map +1 -0
  50. package/dist/sparql/formatter.d.ts +103 -0
  51. package/dist/sparql/formatter.d.ts.map +1 -0
  52. package/dist/sparql/formatter.js +764 -0
  53. package/dist/sparql/formatter.js.map +1 -0
  54. package/dist/token-serializer.d.ts +96 -0
  55. package/dist/token-serializer.d.ts.map +1 -0
  56. package/dist/token-serializer.js +456 -0
  57. package/dist/token-serializer.js.map +1 -0
  58. package/dist/trig/formatter.d.ts +99 -0
  59. package/dist/trig/formatter.d.ts.map +1 -0
  60. package/dist/trig/formatter.js +418 -0
  61. package/dist/trig/formatter.js.map +1 -0
  62. package/dist/trig/serializer.d.ts +39 -0
  63. package/dist/trig/serializer.d.ts.map +1 -0
  64. package/dist/trig/serializer.js +170 -0
  65. package/dist/trig/serializer.js.map +1 -0
  66. package/dist/turtle/formatter.d.ts +56 -0
  67. package/dist/turtle/formatter.d.ts.map +1 -0
  68. package/dist/turtle/formatter.js +325 -0
  69. package/dist/turtle/formatter.js.map +1 -0
  70. package/dist/turtle/serializer.d.ts +87 -0
  71. package/dist/turtle/serializer.d.ts.map +1 -0
  72. package/dist/turtle/serializer.js +343 -0
  73. package/dist/turtle/serializer.js.map +1 -0
  74. package/dist/types.d.ts +323 -0
  75. package/dist/types.d.ts.map +1 -0
  76. package/dist/types.js +14 -0
  77. package/dist/types.js.map +1 -0
  78. package/dist/utils.d.ts +157 -0
  79. package/dist/utils.d.ts.map +1 -0
  80. package/dist/utils.js +446 -0
  81. package/dist/utils.js.map +1 -0
  82. package/package.json +73 -0
@@ -0,0 +1,79 @@
1
+ import { RdfSyntax } from '../types.js';
2
+ import { BaseSerializer } from '../base-serializer.js';
3
+ import { sortQuads } from '../utils.js';
4
+ /**
5
+ * Serializer for N-Triples format (RDF 1.2 compatible).
6
+ *
7
+ * N-Triples is a line-based, plain text format for encoding RDF graphs.
8
+ * Each line contains a single triple: subject predicate object .
9
+ *
10
+ * RDF 1.2 adds support for triple terms (quoted triples) as subjects or objects.
11
+ *
12
+ * @see https://www.w3.org/TR/rdf12-n-triples/
13
+ */
14
+ export class NTriplesSerializer extends BaseSerializer {
15
+ syntax = RdfSyntax.NTriples;
16
+ constructor() {
17
+ super();
18
+ // N-Triples does not support prefixes or shortcuts
19
+ this.supportsPrefixes = false;
20
+ this.supportsRdfTypeShorthand = false;
21
+ // N-Triples 1.2 supports triple terms
22
+ this.supportsRdf12 = true;
23
+ }
24
+ /**
25
+ * Serializes a single quad/triple to N-Triples format.
26
+ *
27
+ * @param quad The quad to serialize.
28
+ * @param options Serialization options.
29
+ * @returns The serialized N-Triple string.
30
+ */
31
+ serializeQuad(quad, options) {
32
+ const opts = this.getOptions(options);
33
+ const subject = this.serializeTerm(quad.subject, opts);
34
+ const predicate = this.serializeTerm(quad.predicate, opts);
35
+ const object = this.serializeTerm(quad.object, opts);
36
+ return `${subject} ${predicate} ${object} .`;
37
+ }
38
+ /**
39
+ * Serializes multiple quads/triples to N-Triples format.
40
+ *
41
+ * @param quads The quads to serialize.
42
+ * @param options Serialization options.
43
+ * @returns The serialized N-Triples string.
44
+ */
45
+ serialize(quads, options) {
46
+ const opts = this.getOptions(options);
47
+ const quadArray = Array.from(quads);
48
+ // Sort if requested
49
+ const sortedQuads = opts.sort ? sortQuads(quadArray) : quadArray;
50
+ const lines = [];
51
+ for (const quad of sortedQuads) {
52
+ // Skip quads with graph (N-Triples doesn't support named graphs)
53
+ if (quad.graph && quad.graph.termType !== 'DefaultGraph') {
54
+ continue;
55
+ }
56
+ lines.push(this.serializeQuad(quad, opts));
57
+ }
58
+ return lines.join(opts.lineEnd) + (lines.length > 0 ? opts.lineEnd : '');
59
+ }
60
+ /**
61
+ * Formats quads with detailed result information.
62
+ */
63
+ format(quads, options) {
64
+ const warnings = [];
65
+ const quadArray = Array.from(quads);
66
+ // Check for unsupported features and add warnings
67
+ for (const quad of quadArray) {
68
+ if (quad.graph && quad.graph.termType !== 'DefaultGraph') {
69
+ warnings.push(`Named graph ignored: N-Triples does not support named graphs.`);
70
+ break;
71
+ }
72
+ }
73
+ return {
74
+ output: this.serialize(quads, options),
75
+ warnings: warnings.length > 0 ? warnings : undefined
76
+ };
77
+ }
78
+ }
79
+ //# sourceMappingURL=serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializer.js","sourceRoot":"","sources":["../../src/ntriples/serializer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;;;GASG;AACH,MAAM,OAAO,kBAAmB,SAAQ,cAAc;IACzC,MAAM,GAAkB,SAAS,CAAC,QAAQ,CAAC;IAEpD;QACI,KAAK,EAAE,CAAC;QACR,mDAAmD;QACnD,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,wBAAwB,GAAG,KAAK,CAAC;QACtC,sCAAsC;QACtC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC9B,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,IAAsB,EAAE,OAA2B;QAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAEtC,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACvD,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAErD,OAAO,GAAG,OAAO,IAAI,SAAS,IAAI,MAAM,IAAI,CAAC;IACjD,CAAC;IAED;;;;;;OAMG;IACH,SAAS,CAAC,KAAiC,EAAE,OAA2B;QACpE,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEpC,oBAAoB;QACpB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEjE,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC7B,iEAAiE;YACjE,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;gBACvD,SAAS;YACb,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED;;OAEG;IACM,MAAM,CAAC,KAAiC,EAAE,OAA2B;QAC1E,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEpC,kDAAkD;QAClD,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,cAAc,EAAE,CAAC;gBACvD,QAAQ,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;gBAC/E,MAAM;YACV,CAAC;QACL,CAAC;QAED,OAAO;YACH,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC;YACtC,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;SACvD,CAAC;IACN,CAAC;CACJ"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Sorting module for RDF quads.
3
+ */
4
+ export { alphabeticalStrategy, createByTypeStrategy, createSemanticStrategy, createPriorityStrategy, applySortingStrategy } from './strategies.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sorting/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACH,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACvB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Sorting module for RDF quads.
3
+ */
4
+ export { alphabeticalStrategy, createByTypeStrategy, createSemanticStrategy, createPriorityStrategy, applySortingStrategy } from './strategies.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sorting/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACH,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACvB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Sorting strategies for RDF quads.
3
+ *
4
+ * These strategies allow customizing the order of quads in serialized output,
5
+ * supporting use cases like grouping by type, semantic ordering (dependencies first),
6
+ * and custom priority ordering.
7
+ */
8
+ import type { Quad } from '@rdfjs/types';
9
+ import type { Rdf12Quad, QuadComparator, SortingStrategy, PriorityStrategyConfig } from '../types.js';
10
+ /**
11
+ * Alphabetical sorting by subject, predicate, object.
12
+ * This is the default sorting strategy.
13
+ */
14
+ export declare const alphabeticalStrategy: SortingStrategy;
15
+ /**
16
+ * Strategy that groups quads by their rdf:type, then sorts alphabetically within each type.
17
+ * Resources without a type are placed according to unmatchedPosition.
18
+ */
19
+ export declare function createByTypeStrategy(config?: {
20
+ /** Where to place resources without rdf:type */
21
+ unmatchedPosition?: 'start' | 'end';
22
+ /** How to sort within each type group */
23
+ secondarySort?: 'alphabetical' | 'none';
24
+ }): SortingStrategy;
25
+ /**
26
+ * Semantic ordering: resources that are referenced by others come before their referents.
27
+ * Uses topological sort to ensure dependencies are defined before they are used.
28
+ */
29
+ export declare function createSemanticStrategy(config?: {
30
+ /** Where to place resources that form cycles (can't be fully ordered) */
31
+ cyclesPosition?: 'start' | 'end';
32
+ }): SortingStrategy;
33
+ /**
34
+ * Priority-based sorting: order resources by their type according to a priority list.
35
+ * Types earlier in the list appear first. Unmatched resources are placed according to config.
36
+ */
37
+ export declare function createPriorityStrategy(config: PriorityStrategyConfig): SortingStrategy;
38
+ /**
39
+ * Applies a sorting strategy to an array of quads.
40
+ *
41
+ * @param quads The quads to sort
42
+ * @param strategy The sorting strategy (strategy object, comparator function, or true for alphabetical)
43
+ * @returns A new sorted array of quads
44
+ */
45
+ export declare function applySortingStrategy(quads: Array<Quad | Rdf12Quad>, strategy: boolean | SortingStrategy | QuadComparator): Array<Quad | Rdf12Quad>;
46
+ //# sourceMappingURL=strategies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.d.ts","sourceRoot":"","sources":["../../src/sorting/strategies.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAGtG;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,eAWlC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE;IAC1C,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACpC,yCAAyC;IACzC,aAAa,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC;CAC3C,GAAG,eAAe,CAgElB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE;IAC5C,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;CACpC,GAAG,eAAe,CAsGlB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,eAAe,CAyEtF;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAChC,KAAK,EAAE,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,EAC9B,QAAQ,EAAE,OAAO,GAAG,eAAe,GAAG,cAAc,GACrD,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC,CAoBzB"}
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Sorting strategies for RDF quads.
3
+ *
4
+ * These strategies allow customizing the order of quads in serialized output,
5
+ * supporting use cases like grouping by type, semantic ordering (dependencies first),
6
+ * and custom priority ordering.
7
+ */
8
+ import { termToString, RDF_TYPE } from '../utils.js';
9
+ /**
10
+ * Alphabetical sorting by subject, predicate, object.
11
+ * This is the default sorting strategy.
12
+ */
13
+ export const alphabeticalStrategy = {
14
+ name: 'alphabetical',
15
+ compare(a, b) {
16
+ const subjectCompare = termToString(a.subject).localeCompare(termToString(b.subject));
17
+ if (subjectCompare !== 0)
18
+ return subjectCompare;
19
+ const predicateCompare = termToString(a.predicate).localeCompare(termToString(b.predicate));
20
+ if (predicateCompare !== 0)
21
+ return predicateCompare;
22
+ return termToString(a.object).localeCompare(termToString(b.object));
23
+ }
24
+ };
25
+ /**
26
+ * Strategy that groups quads by their rdf:type, then sorts alphabetically within each type.
27
+ * Resources without a type are placed according to unmatchedPosition.
28
+ */
29
+ export function createByTypeStrategy(config) {
30
+ const unmatchedPosition = config?.unmatchedPosition ?? 'end';
31
+ const secondarySort = config?.secondarySort ?? 'alphabetical';
32
+ return {
33
+ name: 'byType',
34
+ _typeIndex: new Map(),
35
+ _allTypes: new Set(),
36
+ prepare(quads) {
37
+ this._typeIndex.clear();
38
+ this._allTypes.clear();
39
+ for (const q of quads) {
40
+ if (q.predicate.value === RDF_TYPE && q.object.termType === 'NamedNode') {
41
+ const subj = termToString(q.subject);
42
+ const typeIri = q.object.value;
43
+ this._typeIndex.set(subj, typeIri);
44
+ this._allTypes.add(typeIri);
45
+ }
46
+ }
47
+ },
48
+ compare(a, b) {
49
+ const typeIndex = this._typeIndex;
50
+ const allTypes = Array.from(this._allTypes).sort();
51
+ const subjA = termToString(a.subject);
52
+ const subjB = termToString(b.subject);
53
+ const typeA = typeIndex.get(subjA);
54
+ const typeB = typeIndex.get(subjB);
55
+ // Handle unmatched (no type)
56
+ const hasTypeA = typeA !== undefined;
57
+ const hasTypeB = typeB !== undefined;
58
+ if (!hasTypeA && hasTypeB) {
59
+ return unmatchedPosition === 'start' ? -1 : 1;
60
+ }
61
+ if (hasTypeA && !hasTypeB) {
62
+ return unmatchedPosition === 'start' ? 1 : -1;
63
+ }
64
+ // Both have types or both don't
65
+ if (hasTypeA && hasTypeB) {
66
+ const typeCompare = allTypes.indexOf(typeA).toString().localeCompare(allTypes.indexOf(typeB).toString());
67
+ if (typeCompare !== 0) {
68
+ return typeA.localeCompare(typeB);
69
+ }
70
+ }
71
+ // Secondary sort
72
+ if (secondarySort === 'alphabetical') {
73
+ return subjA.localeCompare(subjB)
74
+ || termToString(a.predicate).localeCompare(termToString(b.predicate))
75
+ || termToString(a.object).localeCompare(termToString(b.object));
76
+ }
77
+ return 0;
78
+ }
79
+ };
80
+ }
81
+ /**
82
+ * Semantic ordering: resources that are referenced by others come before their referents.
83
+ * Uses topological sort to ensure dependencies are defined before they are used.
84
+ */
85
+ export function createSemanticStrategy(config) {
86
+ const cyclesPosition = config?.cyclesPosition ?? 'end';
87
+ return {
88
+ name: 'semantic',
89
+ _subjectOrder: new Map(),
90
+ prepare(quads) {
91
+ const subjectOrder = this._subjectOrder;
92
+ subjectOrder.clear();
93
+ // Build dependency graph
94
+ const subjects = new Set();
95
+ const dependencies = new Map(); // subject → subjects it depends on
96
+ for (const q of quads) {
97
+ const subj = termToString(q.subject);
98
+ subjects.add(subj);
99
+ // If object is a resource that's also a subject, it's a dependency
100
+ if (q.object.termType === 'NamedNode' || q.object.termType === 'BlankNode') {
101
+ const obj = termToString(q.object);
102
+ if (!dependencies.has(subj)) {
103
+ dependencies.set(subj, new Set());
104
+ }
105
+ dependencies.get(subj).add(obj);
106
+ }
107
+ }
108
+ // Topological sort using Kahn's algorithm
109
+ const inDegree = new Map();
110
+ const outEdges = new Map(); // points to dependents
111
+ for (const subj of subjects) {
112
+ inDegree.set(subj, 0);
113
+ outEdges.set(subj, new Set());
114
+ }
115
+ // Build in-degree counts and reverse edges
116
+ for (const [subj, deps] of dependencies) {
117
+ for (const dep of deps) {
118
+ if (subjects.has(dep)) {
119
+ inDegree.set(subj, (inDegree.get(subj) ?? 0) + 1);
120
+ outEdges.get(dep).add(subj);
121
+ }
122
+ }
123
+ }
124
+ // Process nodes with no dependencies first
125
+ const queue = [];
126
+ for (const [subj, degree] of inDegree) {
127
+ if (degree === 0) {
128
+ queue.push(subj);
129
+ }
130
+ }
131
+ queue.sort(); // Alphabetical within same level
132
+ let order = 0;
133
+ const ordered = [];
134
+ while (queue.length > 0) {
135
+ const current = queue.shift();
136
+ subjectOrder.set(current, order++);
137
+ ordered.push(current);
138
+ const dependents = Array.from(outEdges.get(current) ?? []).sort();
139
+ for (const dep of dependents) {
140
+ const newDegree = (inDegree.get(dep) ?? 1) - 1;
141
+ inDegree.set(dep, newDegree);
142
+ if (newDegree === 0) {
143
+ queue.push(dep);
144
+ queue.sort();
145
+ }
146
+ }
147
+ }
148
+ // Handle cycles - remaining subjects not in ordered list
149
+ const cycleOrder = cyclesPosition === 'start' ? -1 : order;
150
+ for (const subj of subjects) {
151
+ if (!subjectOrder.has(subj)) {
152
+ subjectOrder.set(subj, cycleOrder);
153
+ }
154
+ }
155
+ },
156
+ compare(a, b) {
157
+ const subjectOrder = this._subjectOrder;
158
+ const subjA = termToString(a.subject);
159
+ const subjB = termToString(b.subject);
160
+ const orderA = subjectOrder.get(subjA) ?? Infinity;
161
+ const orderB = subjectOrder.get(subjB) ?? Infinity;
162
+ if (orderA !== orderB) {
163
+ return orderA - orderB;
164
+ }
165
+ // Within same subject, sort by predicate then object
166
+ return termToString(a.predicate).localeCompare(termToString(b.predicate))
167
+ || termToString(a.object).localeCompare(termToString(b.object));
168
+ }
169
+ };
170
+ }
171
+ /**
172
+ * Priority-based sorting: order resources by their type according to a priority list.
173
+ * Types earlier in the list appear first. Unmatched resources are placed according to config.
174
+ */
175
+ export function createPriorityStrategy(config) {
176
+ const { typeOrder = [], predicateOrder = [], unmatchedPosition = 'end', unmatchedSort = 'alphabetical' } = config;
177
+ const typeRank = new Map(typeOrder.map((t, i) => [t, i]));
178
+ const predicateRank = new Map(predicateOrder.map((p, i) => [p, i]));
179
+ const unmatchedRank = unmatchedPosition === 'start' ? -1 : typeOrder.length;
180
+ return {
181
+ name: 'priority',
182
+ _typeIndex: new Map(),
183
+ prepare(quads) {
184
+ const typeIndex = this._typeIndex;
185
+ typeIndex.clear();
186
+ for (const q of quads) {
187
+ if (q.predicate.value === RDF_TYPE && q.object.termType === 'NamedNode') {
188
+ const subj = termToString(q.subject);
189
+ const rank = typeRank.get(q.object.value);
190
+ if (rank !== undefined) {
191
+ // Use lowest rank if subject has multiple types
192
+ const existing = typeIndex.get(subj);
193
+ if (existing === undefined || rank < existing) {
194
+ typeIndex.set(subj, rank);
195
+ }
196
+ }
197
+ }
198
+ }
199
+ },
200
+ compare(a, b) {
201
+ const typeIndex = this._typeIndex;
202
+ const subjA = termToString(a.subject);
203
+ const subjB = termToString(b.subject);
204
+ const rankA = typeIndex.get(subjA) ?? unmatchedRank;
205
+ const rankB = typeIndex.get(subjB) ?? unmatchedRank;
206
+ // Primary: by type rank
207
+ if (rankA !== rankB) {
208
+ return rankA - rankB;
209
+ }
210
+ // Secondary: by subject
211
+ const subjCompare = subjA.localeCompare(subjB);
212
+ if (subjCompare !== 0) {
213
+ return subjCompare;
214
+ }
215
+ // Tertiary: by predicate rank if configured
216
+ if (predicateOrder.length > 0) {
217
+ const predRankA = predicateRank.get(a.predicate.value) ?? predicateOrder.length;
218
+ const predRankB = predicateRank.get(b.predicate.value) ?? predicateOrder.length;
219
+ if (predRankA !== predRankB) {
220
+ return predRankA - predRankB;
221
+ }
222
+ }
223
+ // Final: alphabetical within same rank
224
+ if (unmatchedSort === 'alphabetical') {
225
+ return termToString(a.predicate).localeCompare(termToString(b.predicate))
226
+ || termToString(a.object).localeCompare(termToString(b.object));
227
+ }
228
+ return 0;
229
+ }
230
+ };
231
+ }
232
+ /**
233
+ * Applies a sorting strategy to an array of quads.
234
+ *
235
+ * @param quads The quads to sort
236
+ * @param strategy The sorting strategy (strategy object, comparator function, or true for alphabetical)
237
+ * @returns A new sorted array of quads
238
+ */
239
+ export function applySortingStrategy(quads, strategy) {
240
+ if (strategy === false) {
241
+ return quads;
242
+ }
243
+ const sorted = [...quads];
244
+ if (strategy === true) {
245
+ // Default alphabetical
246
+ sorted.sort(alphabeticalStrategy.compare.bind(alphabeticalStrategy));
247
+ }
248
+ else if (typeof strategy === 'function') {
249
+ // Custom comparator function
250
+ sorted.sort(strategy);
251
+ }
252
+ else {
253
+ // Strategy object
254
+ strategy.prepare?.(sorted);
255
+ sorted.sort(strategy.compare.bind(strategy));
256
+ }
257
+ return sorted;
258
+ }
259
+ //# sourceMappingURL=strategies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategies.js","sourceRoot":"","sources":["../../src/sorting/strategies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ import type { IToken } from 'chevrotain';
2
+ import type { ISparqlFormatter, SerializationResult, TokenSerializerOptions } from '../types.js';
3
+ import { BaseTokenFormatter, type BaseFormatterContext, type BaseFormatterOptions } from '../base-token-formatter.js';
4
+ /**
5
+ * SPARQL-specific formatting options.
6
+ */
7
+ export interface SparqlFormatterOptions extends BaseFormatterOptions {
8
+ /**
9
+ * Whether to uppercase SPARQL keywords (SELECT, WHERE, etc.).
10
+ * Default: true
11
+ */
12
+ uppercaseKeywords?: boolean;
13
+ /**
14
+ * Whether to lowercase SPARQL keywords.
15
+ * Default: false (takes precedence if both are true)
16
+ */
17
+ lowercaseKeywords?: boolean;
18
+ /**
19
+ * Whether to align WHERE clause patterns.
20
+ * When true, triple patterns within blocks are aligned.
21
+ * Default: true
22
+ */
23
+ alignPatterns?: boolean;
24
+ /**
25
+ * Whether to put opening braces on the same line as keywords.
26
+ * Default: true
27
+ */
28
+ sameBraceLine?: boolean;
29
+ /**
30
+ * Whether to insert blank lines between major clauses.
31
+ * Default: true
32
+ */
33
+ separateClauses?: boolean;
34
+ }
35
+ /**
36
+ * Internal formatting context that tracks state during token processing.
37
+ */
38
+ interface SparqlFormatterContext extends BaseFormatterContext {
39
+ opts: Required<SparqlFormatterOptions>;
40
+ justEndedPrefix: boolean;
41
+ inWhereBlock: boolean;
42
+ functionCallDepth: number;
43
+ hasFromClause: boolean;
44
+ isAskQuery: boolean;
45
+ /** Tracks if we just closed an inline block */
46
+ lastWasInlineBlock: boolean;
47
+ /** Index in parts[] where the last comment block started (for blank-line repositioning). */
48
+ lastCommentPartIndex: number;
49
+ /** Whether the last comment block already consumed a blank line (from source or clause separation). */
50
+ lastCommentHadBlankLine: boolean;
51
+ /** Whether we are inside a VALUES clause (between VALUES keyword and matching close brace). */
52
+ inValuesClause: boolean;
53
+ /** Depth of the VALUES scope (to match the correct closing brace). */
54
+ valuesDepth: number;
55
+ }
56
+ /**
57
+ * Formatter for SPARQL queries and updates.
58
+ *
59
+ * Uses the W3C-compliant SparqlLexer from mentor-rdf-parsers for tokenization.
60
+ *
61
+ * This formatter can:
62
+ * - Format SPARQL 1.1/1.2 queries and updates
63
+ * - Normalize keyword casing
64
+ * - Apply consistent indentation
65
+ * - Align triple patterns
66
+ * - Preserve comments
67
+ * - Preserve source newlines and blank lines
68
+ *
69
+ * @see https://www.w3.org/TR/sparql12-query/
70
+ */
71
+ export declare class SparqlFormatter extends BaseTokenFormatter<SparqlFormatterContext, SparqlFormatterOptions> implements ISparqlFormatter {
72
+ private lexer;
73
+ formatFromText(query: string, options?: SparqlFormatterOptions): SerializationResult;
74
+ formatFromTokens(tokens: IToken[], options?: SparqlFormatterOptions & TokenSerializerOptions): SerializationResult;
75
+ protected getOptions(options?: SparqlFormatterOptions): Required<SparqlFormatterOptions>;
76
+ protected createContext(opts: Required<SparqlFormatterOptions>): SparqlFormatterContext;
77
+ protected formatTokenValue(token: IToken, opts: Required<SparqlFormatterOptions>): string;
78
+ /**
79
+ * Calculates the length of a block's content (from { to matching }).
80
+ * Returns -1 if the block should use multi-line formatting.
81
+ */
82
+ private calculateBlockLength;
83
+ private shouldBlockBeInline;
84
+ private handleOpenBrace;
85
+ private handleCloseBrace;
86
+ private handleSparqlPeriod;
87
+ private handleSparqlSemicolon;
88
+ private handleSparqlComma;
89
+ private handleSparqlOpenParen;
90
+ private handleSparqlCloseParen;
91
+ private handleGroupComment;
92
+ private handleInlineComment;
93
+ private updateClauseState;
94
+ private handleClauseSeparation;
95
+ private handleTriplePosition;
96
+ private handleLineWrapping;
97
+ private handleSparqlTokenSpacing;
98
+ private detectBlankLines;
99
+ private handleSparqlPrefixIri;
100
+ private formatTokenStream;
101
+ }
102
+ export {};
103
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/sparql/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAa,MAAM,YAAY,CAAC;AAEpD,OAAO,KAAK,EACR,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,EACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACH,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAC5B,MAAM,4BAA4B,CAAC;AAEpC;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,oBAAoB;IAChE;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,UAAU,sBAAuB,SAAQ,oBAAoB;IACzD,IAAI,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,4FAA4F;IAC5F,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uGAAuG;IACvG,uBAAuB,EAAE,OAAO,CAAC;IACjC,+FAA+F;IAC/F,cAAc,EAAE,OAAO,CAAC;IACxB,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eACT,SAAQ,kBAAkB,CAAC,sBAAsB,EAAE,sBAAsB,CACzE,YAAW,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAqB;IAMlC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,mBAAmB;IAWpF,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,sBAAsB,GAAG,mBAAmB;IAUlH,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,QAAQ,CAAC,sBAAsB,CAAC;IAmBxF,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,sBAAsB,CAAC,GAAG,sBAAsB;IAiBvF,SAAS,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,sBAAsB,CAAC,GAAG,MAAM;IAezF;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAoG5B,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,eAAe;IAoDvB,OAAO,CAAC,gBAAgB;IAsCxB,OAAO,CAAC,kBAAkB;IAyB1B,OAAO,CAAC,qBAAqB;IA0C7B,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,qBAAqB;IAsC7B,OAAO,CAAC,sBAAsB;IAwD9B,OAAO,CAAC,kBAAkB;IA2B1B,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,sBAAsB;IAoC9B,OAAO,CAAC,oBAAoB;IAqC5B,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,wBAAwB;IA+ChC,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,iBAAiB;CAmG5B"}