eyeling 1.6.10 → 1.6.12

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/eyeling.js CHANGED
@@ -36,6 +36,12 @@ const STRING_NS = 'http://www.w3.org/2000/10/swap/string#';
36
36
  const SKOLEM_NS = 'https://eyereasoner.github.io/.well-known/genid/';
37
37
  const RDF_JSON_DT = RDF_NS + 'JSON';
38
38
 
39
+ function resolveIriRef(ref, base) {
40
+ if (!base) return ref;
41
+ if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(ref)) return ref; // already absolute
42
+ try { return new URL(ref, base).toString(); } catch { return ref; }
43
+ }
44
+
39
45
  function isRdfJsonDatatype(dt) {
40
46
  // dt comes from literalParts() and may be expanded or prefixed depending on parsing/printing.
41
47
  return dt === null || dt === RDF_JSON_DT || dt === 'rdf:JSON';
@@ -251,6 +257,61 @@ function isNameChar(c) {
251
257
  return /[0-9A-Za-z_\-:]/.test(c);
252
258
  }
253
259
 
260
+ function decodeN3StringEscapes(s) {
261
+ let out = '';
262
+ for (let i = 0; i < s.length; i++) {
263
+ const c = s[i];
264
+ if (c !== '\\') {
265
+ out += c;
266
+ continue;
267
+ }
268
+ if (i + 1 >= s.length) {
269
+ out += '\\';
270
+ continue;
271
+ }
272
+ const e = s[++i];
273
+ switch (e) {
274
+ case 't': out += '\t'; break;
275
+ case 'n': out += '\n'; break;
276
+ case 'r': out += '\r'; break;
277
+ case 'b': out += '\b'; break;
278
+ case 'f': out += '\f'; break;
279
+ case '"': out += '"'; break;
280
+ case "'": out += "'"; break;
281
+ case '\\': out += '\\'; break;
282
+
283
+ case 'u': {
284
+ const hex = s.slice(i + 1, i + 5);
285
+ if (/^[0-9A-Fa-f]{4}$/.test(hex)) {
286
+ out += String.fromCharCode(parseInt(hex, 16));
287
+ i += 4;
288
+ } else {
289
+ out += '\\u';
290
+ }
291
+ break;
292
+ }
293
+
294
+ case 'U': {
295
+ const hex = s.slice(i + 1, i + 9);
296
+ if (/^[0-9A-Fa-f]{8}$/.test(hex)) {
297
+ const cp = parseInt(hex, 16);
298
+ if (cp >= 0 && cp <= 0x10FFFF) out += String.fromCodePoint(cp);
299
+ else out += '\\U' + hex;
300
+ i += 8;
301
+ } else {
302
+ out += '\\U';
303
+ }
304
+ break;
305
+ }
306
+
307
+ default:
308
+ // preserve unknown escapes
309
+ out += '\\' + e;
310
+ }
311
+ }
312
+ return out;
313
+ }
314
+
254
315
  function lex(inputText) {
255
316
  const chars = Array.from(inputText);
256
317
  const n = chars.length;
@@ -384,7 +445,9 @@ function lex(inputText) {
384
445
  sChars.push(cc);
385
446
  }
386
447
  if (!closed) throw new Error('Unterminated long string literal """..."""');
387
- const s = '"""' + sChars.join('') + '"""';
448
+ const raw = '"""' + sChars.join('') + '"""';
449
+ const decoded = decodeN3StringEscapes(stripQuotes(raw));
450
+ const s = JSON.stringify(decoded); // canonical short quoted form
388
451
  tokens.push(new Token('Literal', s));
389
452
  continue;
390
453
  }
@@ -407,7 +470,9 @@ function lex(inputText) {
407
470
  if (cc === '"') break;
408
471
  sChars.push(cc);
409
472
  }
410
- const s = '"' + sChars.join('') + '"';
473
+ const raw = '"' + sChars.join('') + '"';
474
+ const decoded = decodeN3StringEscapes(stripQuotes(raw));
475
+ const s = JSON.stringify(decoded); // canonical short quoted form
411
476
  tokens.push(new Token('Literal', s));
412
477
  continue;
413
478
  }
@@ -864,9 +929,9 @@ class Parser {
864
929
  }
865
930
 
866
931
  if (typ === 'IriRef') {
867
- return new Iri(val || '');
932
+ const base = this.prefixes.map[''] || '';
933
+ return new Iri(resolveIriRef(val || '', base));
868
934
  }
869
-
870
935
  if (typ === 'Ident') {
871
936
  const name = val || '';
872
937
  if (name === 'a') {
@@ -4296,9 +4361,10 @@ function evalBuiltin(goal, subst, facts, backRules, depth, varGen) {
4296
4361
  return s2 !== null ? [s2] : [];
4297
4362
  }
4298
4363
 
4299
- // If neither side is sufficiently instantiated (both vars, or wrong types),
4300
- // we don't enumerate URIs; the builtin just fails.
4301
- return [];
4364
+ const sOk = (g.s instanceof Var) || (g.s instanceof Blank) || (g.s instanceof Iri);
4365
+ const oOk = (g.o instanceof Var) || (g.o instanceof Blank) || (g.o instanceof Literal);
4366
+ if (!sOk || !oOk) return [];
4367
+ return [{ ...subst }];
4302
4368
  }
4303
4369
 
4304
4370
  // -----------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eyeling",
3
- "version": "1.6.10",
3
+ "version": "1.6.12",
4
4
  "description": "A minimal Notation3 (N3) reasoner in JavaScript.",
5
5
  "main": "./index.js",
6
6
  "keywords": [