n3 2.9.1 → 2.10.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.
package/lib/N3Store.js CHANGED
@@ -368,12 +368,15 @@ class N3Store {
368
368
  if (!(index2 = index1[key1])) return 0;
369
369
  return key2 ? key2 in index2 ? 1 : 0 : index2[SIZE];
370
370
  }
371
- for (const value1 in index1) count += index1[value1][SIZE];
371
+ const keys1 = Object.keys(index1);
372
+ for (let i1 = 0; i1 < keys1.length; i1++) count += index1[keys1[i1]][SIZE];
372
373
  return count;
373
374
  }
374
- for (const value0 in index0) {
375
- index1 = index0[value0];
376
- for (const value1 in index1) count += index1[value1][SIZE];
375
+ const keys0 = Object.keys(index0);
376
+ for (let i0 = 0; i0 < keys0.length; i0++) {
377
+ index1 = index0[keys0[i0]];
378
+ const keys1 = Object.keys(index1);
379
+ for (let i1 = 0; i1 < keys1.length; i1++) count += index1[keys1[i1]][SIZE];
377
380
  }
378
381
  return count;
379
382
  }
@@ -863,9 +866,14 @@ class N3Store {
863
866
 
864
867
  // ### `extractLists` finds and removes all list triples
865
868
  // and returns the items per list.
869
+ // With `allowExtraArcs`, lists whose nodes carry arcs other than
870
+ // rdf:first/rdf:rest are returned as well,
871
+ // but left intact when `remove` is set. Ambiguous unreferenced list heads
872
+ // with multiple non-list arcs remain errors.
866
873
  extractLists({
867
874
  remove = false,
868
- ignoreErrors = false
875
+ ignoreErrors = false,
876
+ allowExtraArcs = false
869
877
  } = {}) {
870
878
  // Keys are the list heads' term values, so a null-prototype map keeps
871
879
  // them from colliding with inherited Object members such as `toString`
@@ -876,13 +884,15 @@ class N3Store {
876
884
 
877
885
  // Traverse each list from its tail
878
886
  const tails = this.getQuads(null, _IRIs.default.rdf.rest, _IRIs.default.rdf.nil, null);
879
- const toRemove = remove ? [...tails] : [];
887
+ const toRemove = [];
880
888
  tails.forEach(tailQuad => {
881
889
  const items = []; // the members found as objects of rdf:first quads
882
890
  let malformed = false; // signals whether the current list is malformed
891
+ let extraArcs = false; // signals whether the current list has extra arcs
883
892
  let head; // the head of the list (_:b1 in above example)
884
893
  let headPos; // set to subject or object when head is set
885
894
  const graph = tailQuad.graph; // make sure list is in exactly one graph
895
+ const listQuads = []; // rdf:first/rdf:rest quads of this list
886
896
 
887
897
  // Traverse the list from tail to end
888
898
  let current = tailQuad.subject;
@@ -901,16 +911,20 @@ class N3Store {
901
911
 
902
912
  // one rdf:first
903
913
  else if (quad.predicate.value === _IRIs.default.rdf.first) {
904
- if (first) malformed = onError(current, 'has multiple rdf:first arcs');else toRemove.push(first = quad);
914
+ if (first) malformed = onError(current, 'has multiple rdf:first arcs');else first = quad;
915
+ if (remove && first === quad) listQuads.push(quad);
905
916
  }
906
917
 
907
918
  // one rdf:rest
908
919
  else if (quad.predicate.value === _IRIs.default.rdf.rest) {
909
- if (rest) malformed = onError(current, 'has multiple rdf:rest arcs');else toRemove.push(rest = quad);
920
+ if (rest) malformed = onError(current, 'has multiple rdf:rest arcs');else rest = quad;
921
+ if (remove && rest === quad) listQuads.push(quad);
910
922
  }
911
923
 
912
924
  // alien triple
913
- else if (objectQuads.length) malformed = onError(current, 'can\'t be subject and object');else {
925
+ else if (objectQuads.length) {
926
+ if (allowExtraArcs) extraArcs = true;else malformed = onError(current, `has non-list arc ${quad.predicate.value}`);
927
+ } else {
914
928
  head = quad; // e.g. { (1 2 3) :p :o }
915
929
  headPos = 'subject';
916
930
  }
@@ -936,9 +950,12 @@ class N3Store {
936
950
  }
937
951
 
938
952
  // Don't remove any quads if the list is malformed
939
- if (malformed) remove = false;
940
- // Store the list under the value of its head
941
- else if (head) lists[head[headPos].value] = items;
953
+ if (malformed) remove = false;else {
954
+ // Store the list under the value of its head
955
+ if (head) lists[head[headPos].value] = items;
956
+ // Leave lists with extra arcs fully intact; otherwise queue this list once.
957
+ if (remove && !extraArcs) toRemove.push(...listQuads);
958
+ }
942
959
  });
943
960
 
944
961
  // Remove list quads if requested
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "2.9.1",
3
+ "version": "2.10.0",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
package/src/N3Store.js CHANGED
@@ -394,15 +394,18 @@ export default class N3Store {
394
394
  return key2 ? (key2 in index2 ? 1 : 0) : index2[SIZE];
395
395
  }
396
396
 
397
- for (const value1 in index1)
398
- count += index1[value1][SIZE];
397
+ const keys1 = Object.keys(index1);
398
+ for (let i1 = 0; i1 < keys1.length; i1++)
399
+ count += index1[keys1[i1]][SIZE];
399
400
  return count;
400
401
  }
401
402
 
402
- for (const value0 in index0) {
403
- index1 = index0[value0];
404
- for (const value1 in index1)
405
- count += index1[value1][SIZE];
403
+ const keys0 = Object.keys(index0);
404
+ for (let i0 = 0; i0 < keys0.length; i0++) {
405
+ index1 = index0[keys0[i0]];
406
+ const keys1 = Object.keys(index1);
407
+ for (let i1 = 0; i1 < keys1.length; i1++)
408
+ count += index1[keys1[i1]][SIZE];
406
409
  }
407
410
  return count;
408
411
  }
@@ -913,7 +916,11 @@ export default class N3Store {
913
916
 
914
917
  // ### `extractLists` finds and removes all list triples
915
918
  // and returns the items per list.
916
- extractLists({ remove = false, ignoreErrors = false } = {}) {
919
+ // With `allowExtraArcs`, lists whose nodes carry arcs other than
920
+ // rdf:first/rdf:rest are returned as well,
921
+ // but left intact when `remove` is set. Ambiguous unreferenced list heads
922
+ // with multiple non-list arcs remain errors.
923
+ extractLists({ remove = false, ignoreErrors = false, allowExtraArcs = false } = {}) {
917
924
  // Keys are the list heads' term values, so a null-prototype map keeps
918
925
  // them from colliding with inherited Object members such as `toString`
919
926
  const lists = Object.create(null);
@@ -922,13 +929,15 @@ export default class N3Store {
922
929
 
923
930
  // Traverse each list from its tail
924
931
  const tails = this.getQuads(null, namespaces.rdf.rest, namespaces.rdf.nil, null);
925
- const toRemove = remove ? [...tails] : [];
932
+ const toRemove = [];
926
933
  tails.forEach(tailQuad => {
927
934
  const items = []; // the members found as objects of rdf:first quads
928
935
  let malformed = false; // signals whether the current list is malformed
936
+ let extraArcs = false; // signals whether the current list has extra arcs
929
937
  let head; // the head of the list (_:b1 in above example)
930
938
  let headPos; // set to subject or object when head is set
931
939
  const graph = tailQuad.graph; // make sure list is in exactly one graph
940
+ const listQuads = []; // rdf:first/rdf:rest quads of this list
932
941
 
933
942
  // Traverse the list from tail to end
934
943
  let current = tailQuad.subject;
@@ -950,7 +959,9 @@ export default class N3Store {
950
959
  if (first)
951
960
  malformed = onError(current, 'has multiple rdf:first arcs');
952
961
  else
953
- toRemove.push(first = quad);
962
+ first = quad;
963
+ if (remove && first === quad)
964
+ listQuads.push(quad);
954
965
  }
955
966
 
956
967
  // one rdf:rest
@@ -958,12 +969,18 @@ export default class N3Store {
958
969
  if (rest)
959
970
  malformed = onError(current, 'has multiple rdf:rest arcs');
960
971
  else
961
- toRemove.push(rest = quad);
972
+ rest = quad;
973
+ if (remove && rest === quad)
974
+ listQuads.push(quad);
962
975
  }
963
976
 
964
977
  // alien triple
965
- else if (objectQuads.length)
966
- malformed = onError(current, 'can\'t be subject and object');
978
+ else if (objectQuads.length) {
979
+ if (allowExtraArcs)
980
+ extraArcs = true;
981
+ else
982
+ malformed = onError(current, `has non-list arc ${quad.predicate.value}`);
983
+ }
967
984
  else {
968
985
  head = quad; // e.g. { (1 2 3) :p :o }
969
986
  headPos = 'subject';
@@ -1000,9 +1017,14 @@ export default class N3Store {
1000
1017
  // Don't remove any quads if the list is malformed
1001
1018
  if (malformed)
1002
1019
  remove = false;
1003
- // Store the list under the value of its head
1004
- else if (head)
1005
- lists[head[headPos].value] = items;
1020
+ else {
1021
+ // Store the list under the value of its head
1022
+ if (head)
1023
+ lists[head[headPos].value] = items;
1024
+ // Leave lists with extra arcs fully intact; otherwise queue this list once.
1025
+ if (remove && !extraArcs)
1026
+ toRemove.push(...listQuads);
1027
+ }
1006
1028
  });
1007
1029
 
1008
1030
  // Remove list quads if requested