eyeling 1.27.8 → 1.28.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/README.md CHANGED
@@ -5,6 +5,15 @@
5
5
 
6
6
  A compact [Notation3 (N3)](https://notation3.org/) reasoner in **JavaScript**.
7
7
 
8
+ <table style="background-color: #eef7ff;">
9
+ <tr>
10
+ <td bgcolor="#eef7ff" style="background-color: #eef7ff; padding: 16px;">
11
+ <p><strong>Mission</strong></p>
12
+ <p>Eyeling aims to make knowledge itself computationally accountable, so every conclusion can be derived, checked, and explained. It does this by keeping reasoning close to explicit facts, rules, and proofs rather than hidden assumptions or opaque workflows. As a compact Notation3 reasoner for JavaScript, Eyeling is designed to fit into practical systems while remaining inspectable enough for researchers, engineers, and agents to understand why a result follows. The ambition is not just to process data, but to support a culture of verifiable knowledge: conclusions that can be exchanged, reproduced, challenged, and improved.</p>
13
+ </td>
14
+ </tr>
15
+ </table>
16
+
8
17
  Eyeling is characterized by:
9
18
 
10
19
  - **Notation3 reasoning in a small JavaScript package** — facts, quoted formulas, and N3 rules are parsed and reasoned over directly.
@@ -486,9 +495,19 @@ const result = reasonStream(input, { rdfjs: true });
486
495
  console.log(result.closureQuads);
487
496
  ```
488
497
 
489
- Supported RDF-JS input terms include named nodes, blank nodes, literals, variables, default graph terms, and default-graph quads. Named-graph input quads are rejected clearly unless handled through N3/TriG compatibility mode.
498
+ Supported RDF-JS input terms include named nodes, blank nodes, literals, variables, default graph terms, and RDF 1.2 `Quad` terms in subject/object positions. Input objects may combine `quads`/`dataset`/`facts` with `n3`; Eyeling merges the RDF-JS facts with the N3 text before reasoning.
499
+
500
+ Named-graph RDF-JS input quads are accepted and represented internally with the same shape as RDF/TriG compatibility mode:
501
+
502
+ ```n3
503
+ :graph log:nameOf {
504
+ :s :p :o .
505
+ } .
506
+ ```
507
+
508
+ When `rdfjs: true` is used on output, singleton N3 quoted formulas are converted to RDF-JS `Quad` terms where RDF 1.2 can represent them, and `log:nameOf` graph terms are expanded back into named-graph RDF-JS quads.
490
509
 
491
- Use RDF-JS when you want Eyeling to sit inside a JavaScript RDF pipeline. Use raw N3 input when you need N3-only features such as quoted formulas or N3 rules represented directly in source text.
510
+ Use RDF-JS when you want Eyeling to sit inside a JavaScript RDF pipeline. Use raw N3 input when you need N3-only features such as rules represented directly in source text.
492
511
 
493
512
  ---
494
513
 
@@ -995,7 +1014,7 @@ Package scripts are defined in `package.json`.
995
1014
  | `npm run test:manifest` | Validate example/test manifest expectations. |
996
1015
  | `npm run test:playground` | Check playground serving headers. |
997
1016
  | `npm run test:package` | Verify package-level behavior. |
998
- | `npm run rdf12` | Run RDF 1.2 Turtle, N-Triples, N-Quads, and TriG syntax suites. |
1017
+ | `npm run test:rdf12` | Run RDF 1.2 Turtle, N-Triples, N-Quads, and TriG syntax suites. |
999
1018
  | `npm test` | Build and run the full suite. |
1000
1019
 
1001
1020
  ### Recommended local check before committing
@@ -1176,7 +1195,7 @@ Default CLI output prints newly derived facts. Use `reasonStream()` with `includ
1176
1195
 
1177
1196
  ### RDF-JS conversion fails
1178
1197
 
1179
- Some N3 terms cannot be represented as ordinary RDF-JS quads. Use:
1198
+ RDF 1.2 singleton quoted formulas are converted to RDF-JS `Quad` terms, but general N3 formulas, lists with open tails, and other N3-only terms still cannot be represented as RDF-JS quads. Use:
1180
1199
 
1181
1200
  ```js
1182
1201
  reasonStream(input, { rdfjs: true, skipUnsupportedRdfJs: true });
@@ -6106,7 +6106,7 @@ const {
6106
6106
  } = require('./printing');
6107
6107
  const {
6108
6108
  getDataFactory,
6109
- internalTripleToRdfJsQuad,
6109
+ internalTripleToRdfJsQuads,
6110
6110
  normalizeParsedReasonerInputSync,
6111
6111
  normalizeReasonerInputSync,
6112
6112
  normalizeReasonerInputAsync,
@@ -9604,15 +9604,22 @@ function isUnsupportedRdfJsConversionError(err) {
9604
9604
  );
9605
9605
  }
9606
9606
 
9607
- function maybeTripleToRdfJsQuad(triple, rdfFactory, skipUnsupportedRdfJs) {
9607
+ function maybeTripleToRdfJsQuads(triple, rdfFactory, skipUnsupportedRdfJs) {
9608
9608
  try {
9609
- return internalTripleToRdfJsQuad(triple, rdfFactory);
9609
+ return internalTripleToRdfJsQuads(triple, rdfFactory);
9610
9610
  } catch (err) {
9611
- if (skipUnsupportedRdfJs && isUnsupportedRdfJsConversionError(err)) return null;
9611
+ if (skipUnsupportedRdfJs && isUnsupportedRdfJsConversionError(err)) return [];
9612
9612
  throw err;
9613
9613
  }
9614
9614
  }
9615
9615
 
9616
+ function addRdfJsPayloadQuads(payload, quads) {
9617
+ if (!Array.isArray(quads) || quads.length === 0) return payload;
9618
+ payload.quads = quads;
9619
+ if (quads.length === 1) payload.quad = quads[0];
9620
+ return payload;
9621
+ }
9622
+
9616
9623
  function reasonStream(input, opts = {}) {
9617
9624
  const {
9618
9625
  baseIri = null,
@@ -9640,7 +9647,8 @@ function reasonStream(input, opts = {}) {
9640
9647
  rdf: useRdfCompatibility,
9641
9648
  })
9642
9649
  : null;
9643
- const parsedInput = parsedSourceList || parsedTextInput || normalizeParsedReasonerInputSync(input);
9650
+ const hasInlineN3 = input && typeof input === 'object' && !Array.isArray(input) && typeof input.n3 === 'string';
9651
+ const parsedInput = parsedSourceList || parsedTextInput || (hasInlineN3 ? null : normalizeParsedReasonerInputSync(input));
9644
9652
  const rdfFactory = rdfjs ? getDataFactory(dataFactory) : null;
9645
9653
 
9646
9654
  const __oldEnforceHttps = deref.getEnforceHttpsEnabled();
@@ -9711,8 +9719,7 @@ function reasonStream(input, opts = {}) {
9711
9719
  for (const qdf of queryDerived) {
9712
9720
  const payload = { triple: useRdfCompatibility ? tripleToRdfCompatible(qdf.fact, prefixes) : tripleToN3(qdf.fact, prefixes), df: qdf };
9713
9721
  if (rdfFactory) {
9714
- const quad = maybeTripleToRdfJsQuad(qdf.fact, rdfFactory, skipUnsupportedRdfJs);
9715
- if (quad) payload.quad = quad;
9722
+ addRdfJsPayloadQuads(payload, maybeTripleToRdfJsQuads(qdf.fact, rdfFactory, skipUnsupportedRdfJs));
9716
9723
  }
9717
9724
  onDerived(payload);
9718
9725
  }
@@ -9730,8 +9737,7 @@ function reasonStream(input, opts = {}) {
9730
9737
  df,
9731
9738
  };
9732
9739
  if (rdfFactory) {
9733
- const quad = maybeTripleToRdfJsQuad(df.fact, rdfFactory, skipUnsupportedRdfJs);
9734
- if (quad) payload.quad = quad;
9740
+ addRdfJsPayloadQuads(payload, maybeTripleToRdfJsQuads(df.fact, rdfFactory, skipUnsupportedRdfJs));
9735
9741
  }
9736
9742
  onDerived(payload);
9737
9743
  }
@@ -9772,12 +9778,10 @@ function reasonStream(input, opts = {}) {
9772
9778
  };
9773
9779
 
9774
9780
  if (rdfFactory) {
9775
- __out.closureQuads = closureTriples
9776
- .map((t) => maybeTripleToRdfJsQuad(t, rdfFactory, skipUnsupportedRdfJs))
9777
- .filter(Boolean);
9778
- __out.queryQuads = queryTriples
9779
- .map((t) => maybeTripleToRdfJsQuad(t, rdfFactory, skipUnsupportedRdfJs))
9780
- .filter(Boolean);
9781
+ __out.closureQuads = closureTriples.flatMap((t) =>
9782
+ maybeTripleToRdfJsQuads(t, rdfFactory, skipUnsupportedRdfJs),
9783
+ );
9784
+ __out.queryQuads = queryTriples.flatMap((t) => maybeTripleToRdfJsQuads(t, rdfFactory, skipUnsupportedRdfJs));
9781
9785
  }
9782
9786
  deref.setEnforceHttpsEnabled(__oldEnforceHttps);
9783
9787
  return __out;
@@ -9808,9 +9812,9 @@ function reasonRdfJs(input, opts = {}) {
9808
9812
  ...restOpts,
9809
9813
  rdfjs: false,
9810
9814
  onDerived: ({ df }) => {
9811
- const quad = maybeTripleToRdfJsQuad(df.fact, rdfFactory, skipUnsupportedRdfJs);
9812
- if (quad) {
9813
- queue.push(quad);
9815
+ const quads = maybeTripleToRdfJsQuads(df.fact, rdfFactory, skipUnsupportedRdfJs);
9816
+ if (quads.length) {
9817
+ queue.push(...quads);
9814
9818
  flush();
9815
9819
  }
9816
9820
  },
@@ -14708,6 +14712,7 @@ module.exports = {
14708
14712
 
14709
14713
  const {
14710
14714
  XSD_NS,
14715
+ LOG_NS,
14711
14716
  Literal: InternalLiteral,
14712
14717
  Iri,
14713
14718
  Blank,
@@ -14718,6 +14723,7 @@ const {
14718
14723
  Triple,
14719
14724
  Rule,
14720
14725
  PrefixEnv,
14726
+ annotateQuotedGraphTerm,
14721
14727
  literalParts,
14722
14728
  } = require('./prelude');
14723
14729
  const { termToN3, tripleToN3 } = require('./printing');
@@ -15021,6 +15027,49 @@ function internalRdf12TermToRdfJs(term, factory, position) {
15021
15027
  return internalTermToRdfJs(term, rdfFactory, position);
15022
15028
  }
15023
15029
 
15030
+ function isDefaultGraphTerm(term) {
15031
+ return isRdfJsTerm(term) && term.termType === 'DefaultGraph';
15032
+ }
15033
+
15034
+ function assertDefaultGraphForRdfJsQuadTerm(term, position) {
15035
+ if (!isDefaultGraphTerm(term.graph)) {
15036
+ throw new TypeError(`RDF/JS Quad terms with named graphs are not supported in ${position}`);
15037
+ }
15038
+ }
15039
+
15040
+ function rdfJsGraphNameToInternal(term, position = 'quad.graph') {
15041
+ assertSupportedRdfJsTerm(term, position);
15042
+ switch (term.termType) {
15043
+ case 'NamedNode':
15044
+ return new Iri(term.value);
15045
+ case 'BlankNode':
15046
+ return new Blank(`_:${term.value}`);
15047
+ case 'DefaultGraph':
15048
+ return null;
15049
+ default:
15050
+ throw new TypeError(`Invalid RDF graph termType ${term.termType}`);
15051
+ }
15052
+ }
15053
+
15054
+ function internalGraphNameToRdfJs(term, factory, position = 'graph') {
15055
+ if (term instanceof Iri || term instanceof Blank) return internalTermToRdfJs(term, factory, position);
15056
+ return unsupportedRdfJsTerm(term, position);
15057
+ }
15058
+
15059
+ function graphKey(term) {
15060
+ return `${term.termType}:${term.value}`;
15061
+ }
15062
+
15063
+ function isInternalLogNameOfTriple(triple) {
15064
+ return (
15065
+ triple instanceof Triple &&
15066
+ (triple.s instanceof Iri || triple.s instanceof Blank) &&
15067
+ triple.p instanceof Iri &&
15068
+ triple.p.value === LOG_NS + 'nameOf' &&
15069
+ triple.o instanceof GraphTerm
15070
+ );
15071
+ }
15072
+
15024
15073
  function assertRdfJsQuadShape(subject, predicate, object, graph) {
15025
15074
  if (!['NamedNode', 'BlankNode', 'Quad'].includes(subject.termType)) {
15026
15075
  throw new TypeError(`Invalid RDF subject termType ${subject.termType}`);
@@ -15049,13 +15098,22 @@ function internalTripleToRdfJsQuadInGraph(triple, graph, factory) {
15049
15098
  function internalTripleToRdfJsQuad(triple, factory) {
15050
15099
  const rdfFactory = getDataFactory(factory);
15051
15100
  return rdfFactory.quad(
15052
- internalTermToRdfJs(triple.s, rdfFactory, 'subject'),
15101
+ internalRdf12TermToRdfJs(triple.s, rdfFactory, 'subject'),
15053
15102
  internalTermToRdfJs(triple.p, rdfFactory, 'predicate'),
15054
- internalTermToRdfJs(triple.o, rdfFactory, 'object'),
15103
+ internalRdf12TermToRdfJs(triple.o, rdfFactory, 'object'),
15055
15104
  rdfFactory.defaultGraph(),
15056
15105
  );
15057
15106
  }
15058
15107
 
15108
+ function internalTripleToRdfJsQuads(triple, factory) {
15109
+ const rdfFactory = getDataFactory(factory);
15110
+ if (isInternalLogNameOfTriple(triple)) {
15111
+ const graph = internalGraphNameToRdfJs(triple.s, rdfFactory, 'graph');
15112
+ return (triple.o.triples || []).map((inner) => internalTripleToRdfJsQuadInGraph(inner, graph, rdfFactory));
15113
+ }
15114
+ return [internalTripleToRdfJsQuad(triple, rdfFactory)];
15115
+ }
15116
+
15059
15117
  function escapeStringForN3(value) {
15060
15118
  return JSON.stringify(String(value));
15061
15119
  }
@@ -15087,7 +15145,14 @@ function rdfJsTermToN3(term, position = 'term') {
15087
15145
  return `${lexical}^^<${datatype}>`;
15088
15146
  }
15089
15147
  case 'Quad':
15090
- throw new TypeError(`Quoted triple terms are not supported in ${position}`);
15148
+ if (String(position).endsWith('.predicate') || position === 'quad.predicate' || position === 'predicate') {
15149
+ throw new TypeError(`Quoted triple terms are not valid RDF predicates in ${position}`);
15150
+ }
15151
+ assertDefaultGraphForRdfJsQuadTerm(term, position);
15152
+ return `{ ${rdfJsTermToN3(term.subject, `${position}.subject`)} ${rdfJsTermToN3(
15153
+ term.predicate,
15154
+ `${position}.predicate`,
15155
+ )} ${rdfJsTermToN3(term.object, `${position}.object`)} . }`;
15091
15156
  default:
15092
15157
  throw new TypeError(`Unsupported RDF/JS termType ${JSON.stringify(term.termType)} in ${position}`);
15093
15158
  }
@@ -15107,8 +15172,21 @@ function rdfJsTermToInternal(term, position = 'term') {
15107
15172
  return new InternalLiteral(rdfJsTermToN3(term, position));
15108
15173
  case 'DefaultGraph':
15109
15174
  throw new TypeError(`DefaultGraph is not a valid standalone N3 term in ${position}`);
15110
- case 'Quad':
15111
- throw new TypeError(`Quoted triple terms are not supported in ${position}`);
15175
+ case 'Quad': {
15176
+ if (String(position).endsWith('.predicate') || position === 'quad.predicate' || position === 'predicate') {
15177
+ throw new TypeError(`Quoted triple terms are not valid RDF predicates in ${position}`);
15178
+ }
15179
+ assertDefaultGraphForRdfJsQuadTerm(term, position);
15180
+ return annotateQuotedGraphTerm(
15181
+ new GraphTerm([
15182
+ new Triple(
15183
+ rdfJsTermToInternal(term.subject, `${position}.subject`),
15184
+ rdfJsTermToInternal(term.predicate, `${position}.predicate`),
15185
+ rdfJsTermToInternal(term.object, `${position}.object`),
15186
+ ),
15187
+ ]),
15188
+ );
15189
+ }
15112
15190
  default:
15113
15191
  throw new TypeError(`Unsupported RDF/JS termType ${JSON.stringify(term.termType)} in ${position}`);
15114
15192
  }
@@ -15116,22 +15194,58 @@ function rdfJsTermToInternal(term, position = 'term') {
15116
15194
 
15117
15195
  function rdfJsQuadToInternalTriple(quad) {
15118
15196
  if (!isRdfJsQuad(quad)) throw new TypeError('Expected an RDF/JS Quad');
15119
- if (quad.graph.termType !== 'DefaultGraph') {
15120
- throw new TypeError('Named graph quads are not supported by Eyeling input; use the default graph only');
15121
- }
15122
- return new Triple(
15197
+ const inner = new Triple(
15123
15198
  rdfJsTermToInternal(quad.subject, 'quad.subject'),
15124
15199
  rdfJsTermToInternal(quad.predicate, 'quad.predicate'),
15125
15200
  rdfJsTermToInternal(quad.object, 'quad.object'),
15126
15201
  );
15202
+ const graph = rdfJsGraphNameToInternal(quad.graph, 'quad.graph');
15203
+ if (!graph) return inner;
15204
+ return new Triple(graph, new Iri(LOG_NS + 'nameOf'), annotateQuotedGraphTerm(new GraphTerm([inner])));
15205
+ }
15206
+
15207
+ function rdfJsQuadsToInternalTriples(quads) {
15208
+ const out = [];
15209
+ const namedGraphs = new Map();
15210
+
15211
+ for (const quad of quads) {
15212
+ if (!isRdfJsQuad(quad)) throw new TypeError('Expected an RDF/JS Quad');
15213
+ const inner = new Triple(
15214
+ rdfJsTermToInternal(quad.subject, 'quad.subject'),
15215
+ rdfJsTermToInternal(quad.predicate, 'quad.predicate'),
15216
+ rdfJsTermToInternal(quad.object, 'quad.object'),
15217
+ );
15218
+ const graph = rdfJsGraphNameToInternal(quad.graph, 'quad.graph');
15219
+ if (!graph) {
15220
+ out.push(inner);
15221
+ continue;
15222
+ }
15223
+
15224
+ const key = graphKey(quad.graph);
15225
+ let group = namedGraphs.get(key);
15226
+ if (!group) {
15227
+ group = { graph, triples: [] };
15228
+ namedGraphs.set(key, group);
15229
+ }
15230
+ group.triples.push(inner);
15231
+ }
15232
+
15233
+ for (const { graph, triples } of namedGraphs.values()) {
15234
+ out.push(new Triple(graph, new Iri(LOG_NS + 'nameOf'), annotateQuotedGraphTerm(new GraphTerm(triples))));
15235
+ }
15236
+
15237
+ return out;
15127
15238
  }
15128
15239
 
15129
15240
  function rdfJsQuadToN3(quad) {
15130
15241
  if (!isRdfJsQuad(quad)) throw new TypeError('Expected an RDF/JS Quad');
15131
- if (quad.graph.termType !== 'DefaultGraph') {
15132
- throw new TypeError('Named graph quads are not supported by Eyeling input; use the default graph only');
15133
- }
15134
- return `${rdfJsTermToN3(quad.subject, 'quad.subject')} ${rdfJsTermToN3(quad.predicate, 'quad.predicate')} ${rdfJsTermToN3(quad.object, 'quad.object')}.`;
15242
+ return tripleToN3(rdfJsQuadToInternalTriple(quad), PrefixEnv.newDefault());
15243
+ }
15244
+
15245
+ function rdfJsQuadsToN3(quads) {
15246
+ return rdfJsQuadsToInternalTriples(quads)
15247
+ .map((triple) => tripleToN3(triple, PrefixEnv.newDefault()))
15248
+ .join('\n');
15135
15249
  }
15136
15250
 
15137
15251
  function collectIterableToArray(iterable, label) {
@@ -15176,6 +15290,11 @@ function getPrefixesText(input) {
15176
15290
  return '';
15177
15291
  }
15178
15292
 
15293
+ function getN3Text(input) {
15294
+ if (!isObject(input)) return '';
15295
+ return typeof input.n3 === 'string' ? input.n3 : '';
15296
+ }
15297
+
15179
15298
  function joinN3Sections(parts) {
15180
15299
  return parts
15181
15300
  .filter((part) => typeof part === 'string' && part.length > 0)
@@ -15444,7 +15563,7 @@ function appendSyncQuadFacts(doc, input) {
15444
15563
  const quads = collectIterableToArray(quadsInfo.value, quadsInfo.label);
15445
15564
  return {
15446
15565
  ...doc,
15447
- triples: doc.triples.concat(quads.map((quad) => rdfJsQuadToInternalTriple(quad))),
15566
+ triples: doc.triples.concat(rdfJsQuadsToInternalTriples(quads)),
15448
15567
  };
15449
15568
  }
15450
15569
 
@@ -15454,7 +15573,7 @@ async function appendAsyncQuadFacts(doc, input) {
15454
15573
  const quads = await collectAsyncIterableToArray(quadsInfo.value, quadsInfo.label);
15455
15574
  return {
15456
15575
  ...doc,
15457
- triples: doc.triples.concat(quads.map((quad) => rdfJsQuadToInternalTriple(quad))),
15576
+ triples: doc.triples.concat(rdfJsQuadsToInternalTriples(quads)),
15458
15577
  };
15459
15578
  }
15460
15579
 
@@ -15473,13 +15592,13 @@ async function normalizeParsedReasonerInputAsync(input) {
15473
15592
  function normalizeReasonerInputSync(input) {
15474
15593
  if (typeof input === 'string') return input;
15475
15594
  const parsed = normalizeParsedReasonerInputSync(input);
15476
- if (parsed) return serializeEyelingDocument(parsed);
15595
+ const n3Text = getN3Text(input);
15596
+ if (parsed) return joinN3Sections([n3Text, serializeEyelingDocument(parsed)]);
15477
15597
  if (!isObject(input)) {
15478
15598
  throw new TypeError(
15479
15599
  'Reasoner input must be an N3 string, an Eyeling AST/rule object, or an object containing RDF/JS quads plus optional rules',
15480
15600
  );
15481
15601
  }
15482
- if (typeof input.n3 === 'string') return input.n3;
15483
15602
 
15484
15603
  const quadsInfo = pickInputQuadIterable(input);
15485
15604
  const rulesText = getRulesText(input);
@@ -15487,25 +15606,25 @@ function normalizeReasonerInputSync(input) {
15487
15606
  const prefixesText = getPrefixesText(input);
15488
15607
 
15489
15608
  if (!quadsInfo) {
15490
- if (rulesText || factsText || prefixesText) return joinN3Sections([prefixesText, factsText, rulesText]);
15609
+ if (n3Text || rulesText || factsText || prefixesText) return joinN3Sections([prefixesText, n3Text, factsText, rulesText]);
15491
15610
  throw new TypeError('Input object must provide n3 text, Eyeling AST/rule objects, or RDF/JS quads/facts/dataset');
15492
15611
  }
15493
15612
 
15494
15613
  const quads = collectIterableToArray(quadsInfo.value, quadsInfo.label);
15495
- const quadText = quads.map((quad) => rdfJsQuadToN3(quad)).join('\n');
15496
- return joinN3Sections([prefixesText, factsText, quadText, rulesText]);
15614
+ const quadText = rdfJsQuadsToN3(quads);
15615
+ return joinN3Sections([prefixesText, n3Text, factsText, quadText, rulesText]);
15497
15616
  }
15498
15617
 
15499
15618
  async function normalizeReasonerInputAsync(input) {
15500
15619
  if (typeof input === 'string') return input;
15501
15620
  const parsed = await normalizeParsedReasonerInputAsync(input);
15502
- if (parsed) return serializeEyelingDocument(parsed);
15621
+ const n3Text = getN3Text(input);
15622
+ if (parsed) return joinN3Sections([n3Text, serializeEyelingDocument(parsed)]);
15503
15623
  if (!isObject(input)) {
15504
15624
  throw new TypeError(
15505
15625
  'Reasoner input must be an N3 string, an Eyeling AST/rule object, or an object containing RDF/JS quads plus optional rules',
15506
15626
  );
15507
15627
  }
15508
- if (typeof input.n3 === 'string') return input.n3;
15509
15628
 
15510
15629
  const quadsInfo = pickInputQuadIterable(input);
15511
15630
  const rulesText = getRulesText(input);
@@ -15513,13 +15632,13 @@ async function normalizeReasonerInputAsync(input) {
15513
15632
  const prefixesText = getPrefixesText(input);
15514
15633
 
15515
15634
  if (!quadsInfo) {
15516
- if (rulesText || factsText || prefixesText) return joinN3Sections([prefixesText, factsText, rulesText]);
15635
+ if (n3Text || rulesText || factsText || prefixesText) return joinN3Sections([prefixesText, n3Text, factsText, rulesText]);
15517
15636
  throw new TypeError('Input object must provide n3 text, Eyeling AST/rule objects, or RDF/JS quads/facts/dataset');
15518
15637
  }
15519
15638
 
15520
15639
  const quads = await collectAsyncIterableToArray(quadsInfo.value, quadsInfo.label);
15521
- const quadText = quads.map((quad) => rdfJsQuadToN3(quad)).join('\n');
15522
- return joinN3Sections([prefixesText, factsText, quadText, rulesText]);
15640
+ const quadText = rdfJsQuadsToN3(quads);
15641
+ return joinN3Sections([prefixesText, n3Text, factsText, quadText, rulesText]);
15523
15642
  }
15524
15643
 
15525
15644
  module.exports = {
@@ -15530,8 +15649,10 @@ module.exports = {
15530
15649
  rdfJsTermToN3,
15531
15650
  rdfJsQuadToN3,
15532
15651
  rdfJsQuadToInternalTriple,
15652
+ rdfJsQuadsToInternalTriples,
15533
15653
  internalTermToRdfJs,
15534
15654
  internalTripleToRdfJsQuad,
15655
+ internalTripleToRdfJsQuads,
15535
15656
  internalTripleToRdfJsQuadInGraph,
15536
15657
  normalizeParsedReasonerInputSync,
15537
15658
  normalizeReasonerInputSync,