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.
- package/examples/get-uuid.n3 +18 -14
- package/examples/output/get-uuid.n3 +2 -2
- package/eyeling.js +67 -4
- package/lib/deref.js +27 -4
- package/lib/parser.js +40 -0
- package/package.json +1 -1
package/examples/get-uuid.n3
CHANGED
|
@@ -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
|
-
?
|
|
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
|
-
{
|
|
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
|
-
|
|
65
|
-
} .
|
|
68
|
+
{ ?urnUuid <a> <b> } .
|
|
69
|
+
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
<urn:uuid:
|
|
2
|
-
<urn:uuid:
|
|
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
|
-
|
|
513
|
-
|
|
514
|
-
res.on('
|
|
515
|
-
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
res.on('
|
|
184
|
-
|
|
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();
|