n3 1.17.3 → 1.17.5
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/README.md +12 -5
- package/browser/n3.min.js +1 -1
- package/lib/N3DataFactory.js +1 -1
- package/lib/N3Lexer.js +3 -2
- package/lib/N3Parser.js +6 -6
- package/lib/N3Store.js +78 -70
- package/lib/N3StreamParser.js +1 -1
- package/lib/N3StreamWriter.js +1 -1
- package/lib/N3Util.js +1 -1
- package/lib/N3Writer.js +3 -3
- package/lib/index.js +9 -3
- package/package.json +2 -1
- package/src/N3Lexer.js +1 -0
- package/src/N3Parser.js +5 -5
- package/src/N3Store.js +68 -74
- package/src/N3Writer.js +1 -1
- package/src/index.js +2 -1
package/src/N3Store.js
CHANGED
|
@@ -4,33 +4,22 @@ import { default as N3DataFactory, termToId, termFromId } from './N3DataFactory'
|
|
|
4
4
|
import namespaces from './IRIs';
|
|
5
5
|
import { isDefaultGraph } from './N3Util';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// The number of quads is initially zero
|
|
11
|
-
this._size = 0;
|
|
12
|
-
// `_graphs` contains subject, predicate, and object indexes per graph
|
|
13
|
-
this._graphs = Object.create(null);
|
|
7
|
+
export class N3EntityIndex {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this._id = 1;
|
|
14
10
|
// `_ids` maps entities such as `http://xmlns.com/foaf/0.1/name` to numbers,
|
|
15
11
|
// saving memory by using only numbers as keys in `_graphs`
|
|
16
|
-
this._id = 0;
|
|
17
12
|
this._ids = Object.create(null);
|
|
18
|
-
this.
|
|
13
|
+
this._ids[''] = 1;
|
|
14
|
+
// inverse of `_ids`
|
|
15
|
+
this._entities = Object.create(null);
|
|
16
|
+
this._entities[1] = '';
|
|
19
17
|
// `_blankNodeIndex` is the index of the last automatically named blank node
|
|
20
18
|
this._blankNodeIndex = 0;
|
|
21
|
-
|
|
22
|
-
// Shift parameters if `quads` is not given
|
|
23
|
-
if (!options && quads && !quads[0])
|
|
24
|
-
options = quads, quads = null;
|
|
25
|
-
options = options || {};
|
|
26
19
|
this._factory = options.factory || N3DataFactory;
|
|
27
|
-
|
|
28
|
-
// Add quads if passed
|
|
29
|
-
if (quads)
|
|
30
|
-
this.addQuads(quads);
|
|
31
20
|
}
|
|
32
21
|
|
|
33
|
-
_termFromId(id
|
|
22
|
+
_termFromId(id) {
|
|
34
23
|
if (id[0] === '.') {
|
|
35
24
|
const entities = this._entities;
|
|
36
25
|
const terms = id.split('.');
|
|
@@ -42,7 +31,7 @@ export default class N3Store {
|
|
|
42
31
|
);
|
|
43
32
|
return q;
|
|
44
33
|
}
|
|
45
|
-
return termFromId(id,
|
|
34
|
+
return termFromId(id, this._factory);
|
|
46
35
|
}
|
|
47
36
|
|
|
48
37
|
_termToNumericId(term) {
|
|
@@ -69,6 +58,50 @@ export default class N3Store {
|
|
|
69
58
|
return this._ids[str] || (this._ids[this._entities[++this._id] = str] = this._id);
|
|
70
59
|
}
|
|
71
60
|
|
|
61
|
+
createBlankNode(suggestedName) {
|
|
62
|
+
let name, index;
|
|
63
|
+
// Generate a name based on the suggested name
|
|
64
|
+
if (suggestedName) {
|
|
65
|
+
name = suggestedName = `_:${suggestedName}`, index = 1;
|
|
66
|
+
while (this._ids[name])
|
|
67
|
+
name = suggestedName + index++;
|
|
68
|
+
}
|
|
69
|
+
// Generate a generic blank node name
|
|
70
|
+
else {
|
|
71
|
+
do { name = `_:b${this._blankNodeIndex++}`; }
|
|
72
|
+
while (this._ids[name]);
|
|
73
|
+
}
|
|
74
|
+
// Add the blank node to the entities, avoiding the generation of duplicates
|
|
75
|
+
this._ids[name] = ++this._id;
|
|
76
|
+
this._entities[this._id] = name;
|
|
77
|
+
return this._factory.blankNode(name.substr(2));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ## Constructor
|
|
82
|
+
export default class N3Store {
|
|
83
|
+
constructor(quads, options) {
|
|
84
|
+
// The number of quads is initially zero
|
|
85
|
+
this._size = 0;
|
|
86
|
+
// `_graphs` contains subject, predicate, and object indexes per graph
|
|
87
|
+
this._graphs = Object.create(null);
|
|
88
|
+
|
|
89
|
+
// Shift parameters if `quads` is not given
|
|
90
|
+
if (!options && quads && !quads[0])
|
|
91
|
+
options = quads, quads = null;
|
|
92
|
+
options = options || {};
|
|
93
|
+
this._factory = options.factory || N3DataFactory;
|
|
94
|
+
this._entityIndex = options.entityIndex || new N3EntityIndex({ factory: this._factory });
|
|
95
|
+
this._entities = this._entityIndex._entities;
|
|
96
|
+
this._termFromId = this._entityIndex._termFromId.bind(this._entityIndex);
|
|
97
|
+
this._termToNumericId = this._entityIndex._termToNumericId.bind(this._entityIndex);
|
|
98
|
+
this._termToNewNumericId = this._entityIndex._termToNewNumericId.bind(this._entityIndex);
|
|
99
|
+
|
|
100
|
+
// Add quads if passed
|
|
101
|
+
if (quads)
|
|
102
|
+
this.addQuads(quads);
|
|
103
|
+
}
|
|
104
|
+
|
|
72
105
|
// ## Public properties
|
|
73
106
|
|
|
74
107
|
// ### `size` returns the number of quads in the store
|
|
@@ -127,24 +160,24 @@ export default class N3Store {
|
|
|
127
160
|
*_findInIndex(index0, key0, key1, key2, name0, name1, name2, graphId) {
|
|
128
161
|
let tmp, index1, index2;
|
|
129
162
|
const entityKeys = this._entities;
|
|
130
|
-
const graph = this._termFromId(graphId
|
|
163
|
+
const graph = this._termFromId(entityKeys[graphId]);
|
|
131
164
|
const parts = { subject: null, predicate: null, object: null };
|
|
132
165
|
|
|
133
166
|
// If a key is specified, use only that part of index 0.
|
|
134
167
|
if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
|
|
135
168
|
for (const value0 in index0) {
|
|
136
169
|
if (index1 = index0[value0]) {
|
|
137
|
-
parts[name0] = this._termFromId(entityKeys[value0]
|
|
170
|
+
parts[name0] = this._termFromId(entityKeys[value0]);
|
|
138
171
|
// If a key is specified, use only that part of index 1.
|
|
139
172
|
if (key1) (tmp = index1, index1 = {})[key1] = tmp[key1];
|
|
140
173
|
for (const value1 in index1) {
|
|
141
174
|
if (index2 = index1[value1]) {
|
|
142
|
-
parts[name1] = this._termFromId(entityKeys[value1]
|
|
175
|
+
parts[name1] = this._termFromId(entityKeys[value1]);
|
|
143
176
|
// If a key is specified, use only that part of index 2, if it exists.
|
|
144
177
|
const values = key2 ? (key2 in index2 ? [key2] : []) : Object.keys(index2);
|
|
145
178
|
// Create quads for all items found in index 2.
|
|
146
179
|
for (let l = 0; l < values.length; l++) {
|
|
147
|
-
parts[name2] = this._termFromId(entityKeys[values[l]]
|
|
180
|
+
parts[name2] = this._termFromId(entityKeys[values[l]]);
|
|
148
181
|
yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
|
|
149
182
|
}
|
|
150
183
|
}
|
|
@@ -215,11 +248,8 @@ export default class N3Store {
|
|
|
215
248
|
// ### `_getGraphs` returns an array with the given graph,
|
|
216
249
|
// or all graphs if the argument is null or undefined.
|
|
217
250
|
_getGraphs(graph) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const graphs = {};
|
|
221
|
-
graphs[graph] = this._graphs[graph];
|
|
222
|
-
return graphs;
|
|
251
|
+
graph = graph === '' ? 1 : (graph && (this._termToNumericId(graph) || -1));
|
|
252
|
+
return typeof graph !== 'number' ? this._graphs : { [graph]: this._graphs[graph] };
|
|
223
253
|
}
|
|
224
254
|
|
|
225
255
|
// ### `_uniqueEntities` returns a function that accepts an entity ID
|
|
@@ -253,7 +283,7 @@ export default class N3Store {
|
|
|
253
283
|
predicate = subject.predicate, subject = subject.subject;
|
|
254
284
|
|
|
255
285
|
// Convert terms to internal string representation
|
|
256
|
-
graph =
|
|
286
|
+
graph = graph ? this._termToNewNumericId(graph) : 1;
|
|
257
287
|
|
|
258
288
|
// Find the graph that will contain the triple
|
|
259
289
|
let graphItem = this._graphs[graph];
|
|
@@ -313,9 +343,8 @@ export default class N3Store {
|
|
|
313
343
|
if (!predicate)
|
|
314
344
|
graph = subject.graph, object = subject.object,
|
|
315
345
|
predicate = subject.predicate, subject = subject.subject;
|
|
316
|
-
|
|
317
346
|
// Convert terms to internal string representation
|
|
318
|
-
graph =
|
|
347
|
+
graph = graph ? this._termToNumericId(graph) : 1;
|
|
319
348
|
|
|
320
349
|
// Find internal identifiers for all components
|
|
321
350
|
// and verify the quad exists.
|
|
@@ -380,9 +409,6 @@ export default class N3Store {
|
|
|
380
409
|
// ### `readQuads` returns an generator of quads matching a pattern.
|
|
381
410
|
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
382
411
|
*readQuads(subject, predicate, object, graph) {
|
|
383
|
-
// Convert terms to internal string representation
|
|
384
|
-
graph = graph && termToId(graph);
|
|
385
|
-
|
|
386
412
|
const graphs = this._getGraphs(graph);
|
|
387
413
|
let content, subjectId, predicateId, objectId;
|
|
388
414
|
|
|
@@ -429,15 +455,12 @@ export default class N3Store {
|
|
|
429
455
|
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
430
456
|
// For backwards compatibility, the object return also implements the Readable stream interface.
|
|
431
457
|
match(subject, predicate, object, graph) {
|
|
432
|
-
return new DatasetCoreAndReadableStream(this, subject, predicate, object, graph);
|
|
458
|
+
return new DatasetCoreAndReadableStream(this, subject, predicate, object, graph, { entityIndex: this._entityIndex });
|
|
433
459
|
}
|
|
434
460
|
|
|
435
461
|
// ### `countQuads` returns the number of quads matching a pattern.
|
|
436
462
|
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
437
463
|
countQuads(subject, predicate, object, graph) {
|
|
438
|
-
// Convert terms to internal string representation
|
|
439
|
-
graph = graph && termToId(graph);
|
|
440
|
-
|
|
441
464
|
const graphs = this._getGraphs(graph);
|
|
442
465
|
let count = 0, content, subjectId, predicateId, objectId;
|
|
443
466
|
|
|
@@ -514,9 +537,6 @@ export default class N3Store {
|
|
|
514
537
|
// ### `forSubjects` executes the callback on all subjects that match the pattern.
|
|
515
538
|
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
516
539
|
forSubjects(callback, predicate, object, graph) {
|
|
517
|
-
// Convert terms to internal string representation
|
|
518
|
-
graph = graph && termToId(graph);
|
|
519
|
-
|
|
520
540
|
const graphs = this._getGraphs(graph);
|
|
521
541
|
let content, predicateId, objectId;
|
|
522
542
|
callback = this._uniqueEntities(callback);
|
|
@@ -559,9 +579,6 @@ export default class N3Store {
|
|
|
559
579
|
// ### `forPredicates` executes the callback on all predicates that match the pattern.
|
|
560
580
|
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
561
581
|
forPredicates(callback, subject, object, graph) {
|
|
562
|
-
// Convert terms to internal string representation
|
|
563
|
-
graph = graph && termToId(graph);
|
|
564
|
-
|
|
565
582
|
const graphs = this._getGraphs(graph);
|
|
566
583
|
let content, subjectId, objectId;
|
|
567
584
|
callback = this._uniqueEntities(callback);
|
|
@@ -604,9 +621,6 @@ export default class N3Store {
|
|
|
604
621
|
// ### `forObjects` executes the callback on all objects that match the pattern.
|
|
605
622
|
// Setting any field to `undefined` or `null` indicates a wildcard.
|
|
606
623
|
forObjects(callback, subject, predicate, graph) {
|
|
607
|
-
// Convert terms to internal string representation
|
|
608
|
-
graph = graph && termToId(graph);
|
|
609
|
-
|
|
610
624
|
const graphs = this._getGraphs(graph);
|
|
611
625
|
let content, subjectId, predicateId;
|
|
612
626
|
callback = this._uniqueEntities(callback);
|
|
@@ -653,28 +667,13 @@ export default class N3Store {
|
|
|
653
667
|
this.some(quad => {
|
|
654
668
|
callback(quad.graph);
|
|
655
669
|
return true; // Halt iteration of some()
|
|
656
|
-
}, subject, predicate, object, graph);
|
|
670
|
+
}, subject, predicate, object, this._termFromId(this._entities[graph]));
|
|
657
671
|
}
|
|
658
672
|
}
|
|
659
673
|
|
|
660
674
|
// ### `createBlankNode` creates a new blank node, returning its name
|
|
661
675
|
createBlankNode(suggestedName) {
|
|
662
|
-
|
|
663
|
-
// Generate a name based on the suggested name
|
|
664
|
-
if (suggestedName) {
|
|
665
|
-
name = suggestedName = `_:${suggestedName}`, index = 1;
|
|
666
|
-
while (this._ids[name])
|
|
667
|
-
name = suggestedName + index++;
|
|
668
|
-
}
|
|
669
|
-
// Generate a generic blank node name
|
|
670
|
-
else {
|
|
671
|
-
do { name = `_:b${this._blankNodeIndex++}`; }
|
|
672
|
-
while (this._ids[name]);
|
|
673
|
-
}
|
|
674
|
-
// Add the blank node to the entities, avoiding the generation of duplicates
|
|
675
|
-
this._ids[name] = ++this._id;
|
|
676
|
-
this._entities[this._id] = name;
|
|
677
|
-
return this._factory.blankNode(name.substr(2));
|
|
676
|
+
return this._entityIndex.createBlankNode(suggestedName);
|
|
678
677
|
}
|
|
679
678
|
|
|
680
679
|
// ### `extractLists` finds and removes all list triples
|
|
@@ -783,24 +782,19 @@ export default class N3Store {
|
|
|
783
782
|
}
|
|
784
783
|
}
|
|
785
784
|
|
|
786
|
-
// Determines whether the argument is a string
|
|
787
|
-
function isString(s) {
|
|
788
|
-
return typeof s === 'string' || s instanceof String;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
785
|
/**
|
|
792
786
|
* A class that implements both DatasetCore and Readable.
|
|
793
787
|
*/
|
|
794
788
|
class DatasetCoreAndReadableStream extends Readable {
|
|
795
|
-
constructor(n3Store, subject, predicate, object, graph) {
|
|
789
|
+
constructor(n3Store, subject, predicate, object, graph, options) {
|
|
796
790
|
super({ objectMode: true });
|
|
797
|
-
Object.assign(this, { n3Store, subject, predicate, object, graph });
|
|
791
|
+
Object.assign(this, { n3Store, subject, predicate, object, graph, options });
|
|
798
792
|
}
|
|
799
793
|
|
|
800
794
|
get filtered() {
|
|
801
795
|
if (!this._filtered) {
|
|
802
796
|
const { n3Store, graph, object, predicate, subject } = this;
|
|
803
|
-
const newStore = this._filtered = new N3Store({ factory: n3Store._factory });
|
|
797
|
+
const newStore = this._filtered = new N3Store({ factory: n3Store._factory, entityIndex: this.options.entityIndex });
|
|
804
798
|
for (const quad of n3Store.readQuads(subject, predicate, object, graph))
|
|
805
799
|
newStore.addQuad(quad);
|
|
806
800
|
}
|
|
@@ -830,7 +824,7 @@ class DatasetCoreAndReadableStream extends Readable {
|
|
|
830
824
|
}
|
|
831
825
|
|
|
832
826
|
match(subject, predicate, object, graph) {
|
|
833
|
-
return new DatasetCoreAndReadableStream(this.filtered, subject, predicate, object, graph);
|
|
827
|
+
return new DatasetCoreAndReadableStream(this.filtered, subject, predicate, object, graph, this.options);
|
|
834
828
|
}
|
|
835
829
|
|
|
836
830
|
*[Symbol.iterator]() {
|
package/src/N3Writer.js
CHANGED
|
@@ -225,7 +225,7 @@ export default class N3Writer {
|
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
// ### `_encodeQuad` encodes an RDF
|
|
228
|
+
// ### `_encodeQuad` encodes an RDF-star quad
|
|
229
229
|
_encodeQuad({ subject, predicate, object, graph }) {
|
|
230
230
|
return `<<${
|
|
231
231
|
this._encodeSubject(subject)} ${
|
package/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Lexer from './N3Lexer';
|
|
2
2
|
import Parser from './N3Parser';
|
|
3
3
|
import Writer from './N3Writer';
|
|
4
|
-
import Store from './N3Store';
|
|
4
|
+
import Store, { N3EntityIndex as EntityIndex } from './N3Store';
|
|
5
5
|
import StreamParser from './N3StreamParser';
|
|
6
6
|
import StreamWriter from './N3StreamWriter';
|
|
7
7
|
import * as Util from './N3Util';
|
|
@@ -28,6 +28,7 @@ export {
|
|
|
28
28
|
Parser,
|
|
29
29
|
Writer,
|
|
30
30
|
Store,
|
|
31
|
+
EntityIndex,
|
|
31
32
|
StreamParser,
|
|
32
33
|
StreamWriter,
|
|
33
34
|
Util,
|