eyeling 1.10.10 → 1.10.11

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.
@@ -3,6 +3,7 @@
3
3
  # Example from Wout Slabbinck
4
4
  # ===========================
5
5
 
6
+ @prefix list: <http://www.w3.org/2000/10/swap/list#> .
6
7
  @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
7
8
  @prefix string: <http://www.w3.org/2000/10/swap/string#> .
8
9
  @prefix log: <http://www.w3.org/2000/10/swap/log#> .
@@ -12,16 +13,20 @@
12
13
 
13
14
  # uuid backward rule (component)
14
15
  {
15
- ?input :getUUID ?urnUuid
16
+ ?input :getUUID ?urnUuid
16
17
  }
17
- <=
18
+ <=
18
19
  {
20
+ # 0. add some skolem uri to introduce randomness when there are multiple runs with the same ID
21
+ ( "test" ) log:skolem ?skolem .
22
+ (?input (?skolem) ) list:append ?newList .
23
+
19
24
  # 1. Convert input to a stable string
20
- ?input :listToString ?inputString .
21
-
25
+ ?newList :listToString ?inputString .
26
+
22
27
  # 2. Generate a stable hash (works identically in 2026 eyeJS and Eyeling)
23
28
  ?inputString crypto:sha ?hash .
24
-
29
+
25
30
  # 3. Format the hash into a UUID-compliant structure (8-4-4-4-12)
26
31
  ( ?hash "^(.{8}).*$" ) string:scrape ?p1 .
27
32
  ( ?hash "^.{8}(.{4}).*$" ) string:scrape ?p2 .
@@ -29,7 +34,7 @@
29
34
  ( ?hash "^.{16}(.{4}).*$" ) string:scrape ?p4 .
30
35
  ( ?hash "^.{20}(.{12}).*$" ) string:scrape ?p5 .
31
36
  ( "urn:uuid:" ?p1 "-" ?p2 "-" ?p3 "-" ?p4 "-" ?p5 ) string:concatenation ?urnUuidString .
32
-
37
+
33
38
  # 4. Cast the final string to a URI
34
39
  ?urnUuid log:uri ?urnUuidString .
35
40
  } .
@@ -38,16 +43,16 @@
38
43
  { () :listToString "" } <= { } .
39
44
 
40
45
  # 2. Recursive Case: Process list using rdf:first and rdf:rest
41
- { ?list :listToString ?result } <= {
46
+ { ?list :listToString ?result } <= {
42
47
  ?list rdf:first ?head .
43
48
  ?list rdf:rest ?tail .
44
-
49
+
45
50
  # Convert the current URI to a string
46
51
  ?head log:uri ?headStr .
47
-
52
+
48
53
  # Recursively convert the tail of the list
49
54
  ?tail :listToString ?tailStr .
50
-
55
+
51
56
  # Combine head and tail strings
52
57
  ( ?headStr ?tailStr ) string:concatenation ?result .
53
58
  } .
@@ -55,11 +60,10 @@
55
60
  <test> a odrl:Policy .
56
61
  <lol> a odrl:Policy .
57
62
 
58
- {
63
+ {
59
64
  ?policy a odrl:Policy .
60
65
  ( ?policy ) :getUUID ?urnUuid .
61
66
  }
62
67
  =>
63
- {
64
- ?urnUuid <a> <b> .
65
- } .
68
+ { ?urnUuid <a> <b> } .
69
+
@@ -1,2 +1,2 @@
1
- <urn:uuid:a94a8fe5-ccb1-9ba6-1c4c-0873d391e987> <a> <b> .
2
- <urn:uuid:40392603-3d00-1b52-79df-37cbbe5287b7> <a> <b> .
1
+ <urn:uuid:ad88d7b6-5b37-4eeb-a044-7bca1ffc366c> <a> <b> .
2
+ <urn:uuid:37d41865-0910-9953-46c7-01359fbab6fa> <a> <b> .
package/eyeling.js CHANGED
@@ -493,6 +493,10 @@ function __fetchHttpTextViaSubprocess(url) {
493
493
  path: uu.pathname + uu.search,
494
494
  headers: {
495
495
  'accept': 'text/n3, text/turtle, application/n-triples, application/n-quads, text/plain;q=0.1, */*;q=0.01',
496
+ // Ask for an uncompressed response when possible; some servers send
497
+ // compressed bodies that are not valid UTF-8 text for the parser.
498
+ // We still handle common encodings below if they are returned anyway.
499
+ 'accept-encoding': 'identity',
496
500
  'user-agent': 'eyeling-log-builtins'
497
501
  }
498
502
  };
@@ -509,10 +513,29 @@ function __fetchHttpTextViaSubprocess(url) {
509
513
  console.error('HTTP status ' + sc);
510
514
  process.exit(4);
511
515
  }
512
- res.setEncoding('utf8');
513
- let data = '';
514
- res.on('data', (c) => { data += c; });
515
- res.on('end', () => { process.stdout.write(data); });
516
+ const chunks = [];
517
+ res.on('data', (c) => { chunks.push(c); });
518
+ res.on('end', () => {
519
+ try {
520
+ const { Buffer } = require('buffer');
521
+ const zlib = require('zlib');
522
+ const buf = Buffer.concat(chunks);
523
+ const enc = ((res.headers && res.headers['content-encoding']) || '').toString().toLowerCase();
524
+ let out = buf;
525
+ if (enc.includes('gzip')) out = zlib.gunzipSync(buf);
526
+ else if (enc.includes('deflate')) out = zlib.inflateSync(buf);
527
+ else if (enc.includes('br')) out = zlib.brotliDecompressSync(buf);
528
+ process.stdout.write(out.toString('utf8'));
529
+ } catch (e) {
530
+ // Best-effort fallback: treat as UTF-8.
531
+ try {
532
+ const { Buffer } = require('buffer');
533
+ process.stdout.write(Buffer.concat(chunks).toString('utf8'));
534
+ } catch {
535
+ process.exit(6);
536
+ }
537
+ }
538
+ });
516
539
  });
517
540
  req.on('error', (e) => { console.error(e && e.message ? e.message : String(e)); process.exit(5); });
518
541
  req.end();
@@ -7308,6 +7331,46 @@ class Parser {
7308
7331
  parseGraph() {
7309
7332
  const triples = [];
7310
7333
  while (this.peek().typ !== 'RBrace') {
7334
+ // N3 allows @prefix/@base and SPARQL-style PREFIX/BASE directives anywhere
7335
+ // outside of a triple. This includes inside quoted graph terms.
7336
+ // These directives affect parsing (prefix/base resolution) but do not emit triples.
7337
+ if (this.peek().typ === 'AtPrefix') {
7338
+ this.next();
7339
+ this.parsePrefixDirective();
7340
+ continue;
7341
+ }
7342
+ if (this.peek().typ === 'AtBase') {
7343
+ this.next();
7344
+ this.parseBaseDirective();
7345
+ continue;
7346
+ }
7347
+ if (
7348
+ this.peek().typ === 'Ident' &&
7349
+ typeof this.peek().value === 'string' &&
7350
+ this.peek().value.toLowerCase() === 'prefix' &&
7351
+ this.toks[this.pos + 1] &&
7352
+ this.toks[this.pos + 1].typ === 'Ident' &&
7353
+ typeof this.toks[this.pos + 1].value === 'string' &&
7354
+ this.toks[this.pos + 1].value.endsWith(':') &&
7355
+ this.toks[this.pos + 2] &&
7356
+ (this.toks[this.pos + 2].typ === 'IriRef' || this.toks[this.pos + 2].typ === 'Ident')
7357
+ ) {
7358
+ this.next();
7359
+ this.parseSparqlPrefixDirective();
7360
+ continue;
7361
+ }
7362
+ if (
7363
+ this.peek().typ === 'Ident' &&
7364
+ typeof this.peek().value === 'string' &&
7365
+ this.peek().value.toLowerCase() === 'base' &&
7366
+ this.toks[this.pos + 1] &&
7367
+ (this.toks[this.pos + 1].typ === 'IriRef' || this.toks[this.pos + 1].typ === 'Ident')
7368
+ ) {
7369
+ this.next();
7370
+ this.parseSparqlBaseDirective();
7371
+ continue;
7372
+ }
7373
+
7311
7374
  const left = this.parseTerm();
7312
7375
  if (this.peek().typ === 'OpImplies') {
7313
7376
  this.next();
package/lib/deref.js CHANGED
@@ -162,6 +162,10 @@ function __fetchHttpTextViaSubprocess(url) {
162
162
  path: uu.pathname + uu.search,
163
163
  headers: {
164
164
  'accept': 'text/n3, text/turtle, application/n-triples, application/n-quads, text/plain;q=0.1, */*;q=0.01',
165
+ // Ask for an uncompressed response when possible; some servers send
166
+ // compressed bodies that are not valid UTF-8 text for the parser.
167
+ // We still handle common encodings below if they are returned anyway.
168
+ 'accept-encoding': 'identity',
165
169
  'user-agent': 'eyeling-log-builtins'
166
170
  }
167
171
  };
@@ -178,10 +182,29 @@ function __fetchHttpTextViaSubprocess(url) {
178
182
  console.error('HTTP status ' + sc);
179
183
  process.exit(4);
180
184
  }
181
- res.setEncoding('utf8');
182
- let data = '';
183
- res.on('data', (c) => { data += c; });
184
- res.on('end', () => { process.stdout.write(data); });
185
+ const chunks = [];
186
+ res.on('data', (c) => { chunks.push(c); });
187
+ res.on('end', () => {
188
+ try {
189
+ const { Buffer } = require('buffer');
190
+ const zlib = require('zlib');
191
+ const buf = Buffer.concat(chunks);
192
+ const enc = ((res.headers && res.headers['content-encoding']) || '').toString().toLowerCase();
193
+ let out = buf;
194
+ if (enc.includes('gzip')) out = zlib.gunzipSync(buf);
195
+ else if (enc.includes('deflate')) out = zlib.inflateSync(buf);
196
+ else if (enc.includes('br')) out = zlib.brotliDecompressSync(buf);
197
+ process.stdout.write(out.toString('utf8'));
198
+ } catch (e) {
199
+ // Best-effort fallback: treat as UTF-8.
200
+ try {
201
+ const { Buffer } = require('buffer');
202
+ process.stdout.write(Buffer.concat(chunks).toString('utf8'));
203
+ } catch {
204
+ process.exit(6);
205
+ }
206
+ }
207
+ });
185
208
  });
186
209
  req.on('error', (e) => { console.error(e && e.message ? e.message : String(e)); process.exit(5); });
187
210
  req.end();
package/lib/parser.js CHANGED
@@ -461,6 +461,46 @@ class Parser {
461
461
  parseGraph() {
462
462
  const triples = [];
463
463
  while (this.peek().typ !== 'RBrace') {
464
+ // N3 allows @prefix/@base and SPARQL-style PREFIX/BASE directives anywhere
465
+ // outside of a triple. This includes inside quoted graph terms.
466
+ // These directives affect parsing (prefix/base resolution) but do not emit triples.
467
+ if (this.peek().typ === 'AtPrefix') {
468
+ this.next();
469
+ this.parsePrefixDirective();
470
+ continue;
471
+ }
472
+ if (this.peek().typ === 'AtBase') {
473
+ this.next();
474
+ this.parseBaseDirective();
475
+ continue;
476
+ }
477
+ if (
478
+ this.peek().typ === 'Ident' &&
479
+ typeof this.peek().value === 'string' &&
480
+ this.peek().value.toLowerCase() === 'prefix' &&
481
+ this.toks[this.pos + 1] &&
482
+ this.toks[this.pos + 1].typ === 'Ident' &&
483
+ typeof this.toks[this.pos + 1].value === 'string' &&
484
+ this.toks[this.pos + 1].value.endsWith(':') &&
485
+ this.toks[this.pos + 2] &&
486
+ (this.toks[this.pos + 2].typ === 'IriRef' || this.toks[this.pos + 2].typ === 'Ident')
487
+ ) {
488
+ this.next();
489
+ this.parseSparqlPrefixDirective();
490
+ continue;
491
+ }
492
+ if (
493
+ this.peek().typ === 'Ident' &&
494
+ typeof this.peek().value === 'string' &&
495
+ this.peek().value.toLowerCase() === 'base' &&
496
+ this.toks[this.pos + 1] &&
497
+ (this.toks[this.pos + 1].typ === 'IriRef' || this.toks[this.pos + 1].typ === 'Ident')
498
+ ) {
499
+ this.next();
500
+ this.parseSparqlBaseDirective();
501
+ continue;
502
+ }
503
+
464
504
  const left = this.parseTerm();
465
505
  if (this.peek().typ === 'OpImplies') {
466
506
  this.next();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.10.10",
3
+ "version": "1.10.11",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [