n3 1.17.0 → 1.17.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "1.17.0",
3
+ "version": "1.17.2",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
@@ -35,16 +35,13 @@
35
35
  "@rdfjs/data-model": "^1",
36
36
  "arrayify-stream": "^1.0.0",
37
37
  "browserify": "^17.0.0",
38
- "chai": "^4.0.2",
39
- "chai-things": "^0.2.0",
40
38
  "colors": "^1.1.2",
41
- "docco": "^0.8.0",
39
+ "docco": "^0.9.1",
42
40
  "eslint": "^5.14.1",
43
- "mocha": "^8.0.0",
44
- "nyc": "^14.1.1",
41
+ "jest": "^29.7.0",
45
42
  "pre-commit": "^1.2.2",
46
43
  "rdf-isomorphic": "^1.3.1",
47
- "rdf-test-suite": "^1.19.2",
44
+ "rdf-test-suite": "^1.25.0",
48
45
  "streamify-string": "^1.0.1",
49
46
  "uglify-js": "^3.14.3"
50
47
  },
@@ -52,20 +49,19 @@
52
49
  "build": "npm run build:node && npm run build:browser",
53
50
  "build:node": "babel src -d lib",
54
51
  "build:browser": "rm -rf browser && mkdir browser && browserify -s N3 lib/index.js | uglifyjs > browser/n3.min.js",
55
- "test": "nyc npm run mocha",
56
- "mocha": "mocha",
52
+ "test": "jest",
57
53
  "lint": "eslint src perf test spec",
58
54
  "prepare": "npm run build",
59
55
  "spec": "npm run spec-turtle && npm run spec-ntriples && npm run spec-nquads && npm run spec-trig",
60
56
  "spec-earl": "npm run spec-earl-turtle && npm run spec-earl-ntriples && npm run spec-earl-nquads && npm run spec-earl-trig",
61
- "spec-ntriples": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/ntriples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/",
62
- "spec-nquads": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/nquads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/",
63
- "spec-turtle": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/",
64
- "spec-trig": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/",
65
- "spec-earl-ntriples": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/ntriples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-ntriples.ttl",
66
- "spec-earl-nquads": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/nquads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-nquads.ttl",
67
- "spec-earl-turtle": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-turtle.ttl",
68
- "spec-earl-trig": "rdf-test-suite spec/parser.js http://w3c.github.io/rdf-tests/trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-trig.ttl",
57
+ "spec-ntriples": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-triples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/",
58
+ "spec-nquads": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-quads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/",
59
+ "spec-turtle": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/",
60
+ "spec-trig": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/",
61
+ "spec-earl-ntriples": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-triples/manifest.ttl -i '{ \"format\": \"n-triples\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-ntriples.ttl",
62
+ "spec-earl-nquads": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-n-quads/manifest.ttl -i '{ \"format\": \"n-quads\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-nquads.ttl",
63
+ "spec-earl-turtle": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-turtle/manifest.ttl -i '{ \"format\": \"turtle\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-turtle.ttl",
64
+ "spec-earl-trig": "rdf-test-suite spec/parser.js https://w3c.github.io/rdf-tests/rdf/rdf11/rdf-trig/manifest.ttl -i '{ \"format\": \"trig\" }' -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > spec/earl-trig.ttl",
69
65
  "spec-clean": "rm -r .rdf-test-suite-cache/",
70
66
  "docs": "cd src && docco *.js -o ../docs && cd .."
71
67
  },
@@ -79,5 +75,32 @@
79
75
  "pre-commit": [
80
76
  "lint",
81
77
  "test"
82
- ]
78
+ ],
79
+ "jest": {
80
+ "testMatch": [
81
+ "**/test/*-test.js"
82
+ ],
83
+ "collectCoverage": true,
84
+ "coverageReporters": [
85
+ "json-summary",
86
+ "text",
87
+ "lcov"
88
+ ],
89
+ "coverageThreshold": {
90
+ "global": {
91
+ "branches": 100,
92
+ "functions": 100,
93
+ "lines": 100,
94
+ "statements": 100
95
+ }
96
+ }
97
+ },
98
+ "release": {
99
+ "branches": [
100
+ "main"
101
+ ]
102
+ },
103
+ "publishConfig": {
104
+ "access": "public"
105
+ }
83
106
  }
@@ -10,7 +10,6 @@ let DEFAULTGRAPH;
10
10
  let _blankNodeCounter = 0;
11
11
 
12
12
  const escapedLiteral = /^"(.*".*)(?="[^"]*$)/;
13
- const quadId = /^<<("(?:""|[^"])*"[^ ]*|[^ ]+) ("(?:""|[^"])*"[^ ]*|[^ ]+) ("(?:""|[^"])*"[^ ]*|[^ ]+) ?("(?:""|[^"])*"[^ ]*|[^ ]+)?>>$/;
14
13
 
15
14
  // ## DataFactory singleton
16
15
  const DataFactory = {
@@ -188,9 +187,12 @@ export class DefaultGraph extends Term {
188
187
  // ## DefaultGraph singleton
189
188
  DEFAULTGRAPH = new DefaultGraph();
190
189
 
191
-
192
190
  // ### Constructs a term from the given internal string ID
193
- export function termFromId(id, factory) {
191
+ // The third 'nested' parameter of this function is to aid
192
+ // with recursion over nested terms. It should not be used
193
+ // by consumers of this library.
194
+ // See https://github.com/rdfjs/N3.js/pull/311#discussion_r1061042725
195
+ export function termFromId(id, factory, nested) {
194
196
  factory = factory || DataFactory;
195
197
 
196
198
  // Falsy value or empty string indicate the default graph
@@ -215,21 +217,28 @@ export function termFromId(id, factory) {
215
217
  return factory.literal(id.substr(1, endPos - 1),
216
218
  id[endPos + 1] === '@' ? id.substr(endPos + 2)
217
219
  : factory.namedNode(id.substr(endPos + 3)));
218
- case '<':
219
- const components = quadId.exec(id);
220
- return factory.quad(
221
- termFromId(unescapeQuotes(components[1]), factory),
222
- termFromId(unescapeQuotes(components[2]), factory),
223
- termFromId(unescapeQuotes(components[3]), factory),
224
- components[4] && termFromId(unescapeQuotes(components[4]), factory)
225
- );
220
+ case '[':
221
+ id = JSON.parse(id);
222
+ break;
226
223
  default:
227
- return factory.namedNode(id);
224
+ if (!nested || !Array.isArray(id)) {
225
+ return factory.namedNode(id);
226
+ }
228
227
  }
228
+ return factory.quad(
229
+ termFromId(id[0], factory, true),
230
+ termFromId(id[1], factory, true),
231
+ termFromId(id[2], factory, true),
232
+ id[3] && termFromId(id[3], factory, true)
233
+ );
229
234
  }
230
235
 
231
236
  // ### Constructs an internal string ID from the given term or ID string
232
- export function termToId(term) {
237
+ // The third 'nested' parameter of this function is to aid
238
+ // with recursion over nested terms. It should not be used
239
+ // by consumers of this library.
240
+ // See https://github.com/rdfjs/N3.js/pull/311#discussion_r1061042725
241
+ export function termToId(term, nested) {
233
242
  if (typeof term === 'string')
234
243
  return term;
235
244
  if (term instanceof Term && term.termType !== 'Quad')
@@ -247,17 +256,15 @@ export function termToId(term) {
247
256
  term.language ? `@${term.language}` :
248
257
  (term.datatype && term.datatype.value !== xsd.string ? `^^${term.datatype.value}` : '')}`;
249
258
  case 'Quad':
250
- // To identify RDF* quad components, we escape quotes by doubling them.
251
- // This avoids the overhead of backslash parsing of Turtle-like syntaxes.
252
- return `<<${
253
- escapeQuotes(termToId(term.subject))
254
- } ${
255
- escapeQuotes(termToId(term.predicate))
256
- } ${
257
- escapeQuotes(termToId(term.object))
258
- }${
259
- (isDefaultGraph(term.graph)) ? '' : ` ${termToId(term.graph)}`
260
- }>>`;
259
+ const res = [
260
+ termToId(term.subject, true),
261
+ termToId(term.predicate, true),
262
+ termToId(term.object, true),
263
+ ];
264
+ if (!isDefaultGraph(term.graph)) {
265
+ res.push(termToId(term.graph, true));
266
+ }
267
+ return nested ? res : JSON.stringify(res);
261
268
  default: throw new Error(`Unexpected termType: ${term.termType}`);
262
269
  }
263
270
  }
package/src/N3Store.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { default as N3DataFactory, termToId, termFromId } from './N3DataFactory';
3
3
  import { Readable } from 'readable-stream';
4
4
  import namespaces from './IRIs';
5
+ import { isDefaultGraph } from './N3Util';
5
6
 
6
7
  // ## Constructor
7
8
  export default class N3Store {
@@ -14,7 +15,6 @@ export default class N3Store {
14
15
  // saving memory by using only numbers as keys in `_graphs`
15
16
  this._id = 0;
16
17
  this._ids = Object.create(null);
17
- this._ids['><'] = 0; // dummy entry, so the first actual key is non-zero
18
18
  this._entities = Object.create(null); // inverse of `_ids`
19
19
  // `_blankNodeIndex` is the index of the last automatically named blank node
20
20
  this._blankNodeIndex = 0;
@@ -30,6 +30,45 @@ export default class N3Store {
30
30
  this.addQuads(quads);
31
31
  }
32
32
 
33
+ _termFromId(id, factory) {
34
+ if (id[0] === '.') {
35
+ const entities = this._entities;
36
+ const terms = id.split('.');
37
+ const q = this._factory.quad(
38
+ this._termFromId(entities[terms[1]]),
39
+ this._termFromId(entities[terms[2]]),
40
+ this._termFromId(entities[terms[3]]),
41
+ terms[4] && this._termFromId(entities[terms[4]])
42
+ );
43
+ return q;
44
+ }
45
+ return termFromId(id, factory);
46
+ }
47
+
48
+ _termToNumericId(term) {
49
+ if (term.termType === 'Quad') {
50
+ const s = this._termToNumericId(term.subject),
51
+ p = this._termToNumericId(term.predicate),
52
+ o = this._termToNumericId(term.object);
53
+ let g;
54
+
55
+ return s && p && o && (isDefaultGraph(term.graph) || (g = this._termToNumericId(term.graph))) &&
56
+ this._ids[g ? `.${s}.${p}.${o}.${g}` : `.${s}.${p}.${o}`];
57
+ }
58
+ return this._ids[termToId(term)];
59
+ }
60
+
61
+ _termToNewNumericId(term) {
62
+ // This assumes that no graph term is present - we may wish to error if there is one
63
+ const str = term && term.termType === 'Quad' ?
64
+ `.${this._termToNewNumericId(term.subject)}.${this._termToNewNumericId(term.predicate)}.${this._termToNewNumericId(term.object)}${
65
+ isDefaultGraph(term.graph) ? '' : `.${this._termToNewNumericId(term.graph)}`
66
+ }`
67
+ : termToId(term);
68
+
69
+ return this._ids[str] || (this._ids[this._entities[++this._id] = str] = this._id);
70
+ }
71
+
33
72
  // ## Public properties
34
73
 
35
74
  // ### `size` returns the number of quads in the store
@@ -88,24 +127,24 @@ export default class N3Store {
88
127
  *_findInIndex(index0, key0, key1, key2, name0, name1, name2, graphId) {
89
128
  let tmp, index1, index2;
90
129
  const entityKeys = this._entities;
91
- const graph = termFromId(graphId, this._factory);
130
+ const graph = this._termFromId(graphId, this._factory);
92
131
  const parts = { subject: null, predicate: null, object: null };
93
132
 
94
133
  // If a key is specified, use only that part of index 0.
95
134
  if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
96
135
  for (const value0 in index0) {
97
136
  if (index1 = index0[value0]) {
98
- parts[name0] = termFromId(entityKeys[value0], this._factory);
137
+ parts[name0] = this._termFromId(entityKeys[value0], this._factory);
99
138
  // If a key is specified, use only that part of index 1.
100
139
  if (key1) (tmp = index1, index1 = {})[key1] = tmp[key1];
101
140
  for (const value1 in index1) {
102
141
  if (index2 = index1[value1]) {
103
- parts[name1] = termFromId(entityKeys[value1], this._factory);
142
+ parts[name1] = this._termFromId(entityKeys[value1], this._factory);
104
143
  // If a key is specified, use only that part of index 2, if it exists.
105
144
  const values = key2 ? (key2 in index2 ? [key2] : []) : Object.keys(index2);
106
145
  // Create quads for all items found in index 2.
107
146
  for (let l = 0; l < values.length; l++) {
108
- parts[name2] = termFromId(entityKeys[values[l]], this._factory);
147
+ parts[name2] = this._termFromId(entityKeys[values[l]], this._factory);
109
148
  yield this._factory.quad(parts.subject, parts.predicate, parts.object, graph);
110
149
  }
111
150
  }
@@ -190,7 +229,7 @@ export default class N3Store {
190
229
  return id => {
191
230
  if (!(id in uniqueIds)) {
192
231
  uniqueIds[id] = true;
193
- callback(termFromId(this._entities[id], this._factory));
232
+ callback(this._termFromId(this._entities[id], this._factory));
194
233
  }
195
234
  };
196
235
  }
@@ -214,9 +253,6 @@ export default class N3Store {
214
253
  predicate = subject.predicate, subject = subject.subject;
215
254
 
216
255
  // Convert terms to internal string representation
217
- subject = termToId(subject);
218
- predicate = termToId(predicate);
219
- object = termToId(object);
220
256
  graph = termToId(graph);
221
257
 
222
258
  // Find the graph that will contain the triple
@@ -232,11 +268,9 @@ export default class N3Store {
232
268
  // Since entities can often be long IRIs, we avoid storing them in every index.
233
269
  // Instead, we have a separate index that maps entities to numbers,
234
270
  // which are then used as keys in the other indexes.
235
- const ids = this._ids;
236
- const entities = this._entities;
237
- subject = ids[subject] || (ids[entities[++this._id] = subject] = this._id);
238
- predicate = ids[predicate] || (ids[entities[++this._id] = predicate] = this._id);
239
- object = ids[object] || (ids[entities[++this._id] = object] = this._id);
271
+ subject = this._termToNewNumericId(subject);
272
+ predicate = this._termToNewNumericId(predicate);
273
+ object = this._termToNewNumericId(object);
240
274
 
241
275
  const changed = this._addToIndex(graphItem.subjects, subject, predicate, object);
242
276
  this._addToIndex(graphItem.predicates, predicate, object, subject);
@@ -281,17 +315,14 @@ export default class N3Store {
281
315
  predicate = subject.predicate, subject = subject.subject;
282
316
 
283
317
  // Convert terms to internal string representation
284
- subject = termToId(subject);
285
- predicate = termToId(predicate);
286
- object = termToId(object);
287
318
  graph = termToId(graph);
288
319
 
289
320
  // Find internal identifiers for all components
290
321
  // and verify the quad exists.
291
- const ids = this._ids, graphs = this._graphs;
322
+ const graphs = this._graphs;
292
323
  let graphItem, subjects, predicates;
293
- if (!(subject = ids[subject]) || !(predicate = ids[predicate]) ||
294
- !(object = ids[object]) || !(graphItem = graphs[graph]) ||
324
+ if (!(subject = subject && this._termToNumericId(subject)) || !(predicate = predicate && this._termToNumericId(predicate)) ||
325
+ !(object = object && this._termToNumericId(object)) || !(graphItem = graphs[graph]) ||
295
326
  !(subjects = graphItem.subjects[subject]) ||
296
327
  !(predicates = subjects[predicate]) ||
297
328
  !(object in predicates))
@@ -350,18 +381,15 @@ export default class N3Store {
350
381
  // Setting any field to `undefined` or `null` indicates a wildcard.
351
382
  *readQuads(subject, predicate, object, graph) {
352
383
  // Convert terms to internal string representation
353
- subject = subject && termToId(subject);
354
- predicate = predicate && termToId(predicate);
355
- object = object && termToId(object);
356
384
  graph = graph && termToId(graph);
357
385
 
358
- const graphs = this._getGraphs(graph), ids = this._ids;
386
+ const graphs = this._getGraphs(graph);
359
387
  let content, subjectId, predicateId, objectId;
360
388
 
361
389
  // Translate IRIs to internal index keys.
362
- if (isString(subject) && !(subjectId = ids[subject]) ||
363
- isString(predicate) && !(predicateId = ids[predicate]) ||
364
- isString(object) && !(objectId = ids[object]))
390
+ if (subject && !(subjectId = this._termToNumericId(subject)) ||
391
+ predicate && !(predicateId = this._termToNumericId(predicate)) ||
392
+ object && !(objectId = this._termToNumericId(object)))
365
393
  return;
366
394
 
367
395
  for (const graphId in graphs) {
@@ -408,18 +436,15 @@ export default class N3Store {
408
436
  // Setting any field to `undefined` or `null` indicates a wildcard.
409
437
  countQuads(subject, predicate, object, graph) {
410
438
  // Convert terms to internal string representation
411
- subject = subject && termToId(subject);
412
- predicate = predicate && termToId(predicate);
413
- object = object && termToId(object);
414
439
  graph = graph && termToId(graph);
415
440
 
416
- const graphs = this._getGraphs(graph), ids = this._ids;
441
+ const graphs = this._getGraphs(graph);
417
442
  let count = 0, content, subjectId, predicateId, objectId;
418
443
 
419
444
  // Translate IRIs to internal index keys.
420
- if (isString(subject) && !(subjectId = ids[subject]) ||
421
- isString(predicate) && !(predicateId = ids[predicate]) ||
422
- isString(object) && !(objectId = ids[object]))
445
+ if (subject && !(subjectId = this._termToNumericId(subject)) ||
446
+ predicate && !(predicateId = this._termToNumericId(predicate)) ||
447
+ object && !(objectId = this._termToNumericId(object)))
423
448
  return 0;
424
449
 
425
450
  for (const graphId in graphs) {
@@ -490,17 +515,15 @@ export default class N3Store {
490
515
  // Setting any field to `undefined` or `null` indicates a wildcard.
491
516
  forSubjects(callback, predicate, object, graph) {
492
517
  // Convert terms to internal string representation
493
- predicate = predicate && termToId(predicate);
494
- object = object && termToId(object);
495
518
  graph = graph && termToId(graph);
496
519
 
497
- const ids = this._ids, graphs = this._getGraphs(graph);
520
+ const graphs = this._getGraphs(graph);
498
521
  let content, predicateId, objectId;
499
522
  callback = this._uniqueEntities(callback);
500
523
 
501
524
  // Translate IRIs to internal index keys.
502
- if (isString(predicate) && !(predicateId = ids[predicate]) ||
503
- isString(object) && !(objectId = ids[object]))
525
+ if (predicate && !(predicateId = this._termToNumericId(predicate)) ||
526
+ object && !(objectId = this._termToNumericId(object)))
504
527
  return;
505
528
 
506
529
  for (graph in graphs) {
@@ -537,17 +560,15 @@ export default class N3Store {
537
560
  // Setting any field to `undefined` or `null` indicates a wildcard.
538
561
  forPredicates(callback, subject, object, graph) {
539
562
  // Convert terms to internal string representation
540
- subject = subject && termToId(subject);
541
- object = object && termToId(object);
542
563
  graph = graph && termToId(graph);
543
564
 
544
- const ids = this._ids, graphs = this._getGraphs(graph);
565
+ const graphs = this._getGraphs(graph);
545
566
  let content, subjectId, objectId;
546
567
  callback = this._uniqueEntities(callback);
547
568
 
548
569
  // Translate IRIs to internal index keys.
549
- if (isString(subject) && !(subjectId = ids[subject]) ||
550
- isString(object) && !(objectId = ids[object]))
570
+ if (subject && !(subjectId = this._termToNumericId(subject)) ||
571
+ object && !(objectId = this._termToNumericId(object)))
551
572
  return;
552
573
 
553
574
  for (graph in graphs) {
@@ -584,17 +605,15 @@ export default class N3Store {
584
605
  // Setting any field to `undefined` or `null` indicates a wildcard.
585
606
  forObjects(callback, subject, predicate, graph) {
586
607
  // Convert terms to internal string representation
587
- subject = subject && termToId(subject);
588
- predicate = predicate && termToId(predicate);
589
608
  graph = graph && termToId(graph);
590
609
 
591
- const ids = this._ids, graphs = this._getGraphs(graph);
610
+ const graphs = this._getGraphs(graph);
592
611
  let content, subjectId, predicateId;
593
612
  callback = this._uniqueEntities(callback);
594
613
 
595
614
  // Translate IRIs to internal index keys.
596
- if (isString(subject) && !(subjectId = ids[subject]) ||
597
- isString(predicate) && !(predicateId = ids[predicate]))
615
+ if (subject && !(subjectId = this._termToNumericId(subject)) ||
616
+ predicate && !(predicateId = this._termToNumericId(predicate)))
598
617
  return;
599
618
 
600
619
  for (graph in graphs) {
package/src/N3Writer.js CHANGED
@@ -19,8 +19,8 @@ const escape = /["\\\t\n\r\b\f\u0000-\u0019\ud800-\udbff]/,
19
19
  class SerializedTerm extends Term {
20
20
  // Pretty-printed nodes are not equal to any other node
21
21
  // (e.g., [] does not equal [])
22
- equals() {
23
- return false;
22
+ equals(other) {
23
+ return other === this;
24
24
  }
25
25
  }
26
26