eyeling 1.26.7 → 1.27.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/HANDBOOK.md +32 -1
- package/dist/browser/eyeling.browser.js +396 -3
- package/examples/deck/act-barley-seed-lineage.md +1 -1
- package/examples/deck/faltings-genus2-finiteness.md +1 -1
- package/examples/deck/high-trust-rdf-bloom-envelope.md +1 -1
- package/examples/deck/odrl-dpv-risk-ranked.md +1 -1
- package/examples/deck/rdf-message-cold-chain-recall.md +71 -0
- package/examples/deck/rdf-message-flow.md +1 -1
- package/examples/deck/rdf-message-ldes-incremental.md +94 -0
- package/examples/deck/rdf-message-window-repair.md +1 -1
- package/examples/deck/schema-foaf-mapping.md +2 -0
- package/examples/input/rdf-message-cold-chain-recall.trig +668 -0
- package/examples/input/rdf-message-flow.trig +3 -0
- package/examples/input/rdf-message-ldes-incremental.trig +564 -0
- package/examples/input/rdf-message-microgrid.trig +3 -0
- package/examples/input/rdf-message-window-repair.trig +3 -0
- package/examples/input/rdf-messages.trig +3 -0
- package/examples/output/rdf-message-cold-chain-recall.md +13 -0
- package/examples/output/rdf-message-ldes-incremental.md +13 -0
- package/examples/rdf-message-cold-chain-recall.n3 +229 -0
- package/examples/rdf-message-flow.n3 +3 -0
- package/examples/rdf-message-ldes-incremental.n3 +231 -0
- package/examples/rdf-message-microgrid.n3 +3 -0
- package/examples/rdf-message-window-repair.n3 +3 -0
- package/examples/rdf-messages.n3 +3 -0
- package/eyeling.js +396 -3
- package/lib/cli.js +396 -3
- package/package.json +5 -3
- package/test/examples.test.js +25 -14
- package/test/fixtures/marc-rules-stream-messages.n3 +192 -0
- package/test/stream_messages.test.js +243 -0
package/eyeling.js
CHANGED
|
@@ -4622,12 +4622,15 @@ module.exports = {
|
|
|
4622
4622
|
|
|
4623
4623
|
'use strict';
|
|
4624
4624
|
|
|
4625
|
+
const fs = require('node:fs');
|
|
4625
4626
|
const path = require('node:path');
|
|
4626
|
-
const { pathToFileURL } = require('node:url');
|
|
4627
|
+
const { pathToFileURL, fileURLToPath } = require('node:url');
|
|
4628
|
+
const { TextDecoder } = require('node:util');
|
|
4627
4629
|
|
|
4628
4630
|
const engine = require('./engine');
|
|
4629
4631
|
const deref = require('./deref');
|
|
4630
4632
|
const { PrefixEnv } = require('./prelude');
|
|
4633
|
+
const { normalizeRdfCompatibility } = require('./lexer');
|
|
4631
4634
|
const { parseN3Text, mergeParsedDocuments } = require('./multisource');
|
|
4632
4635
|
|
|
4633
4636
|
function offsetToLineCol(text, offset) {
|
|
@@ -4666,7 +4669,6 @@ function formatN3SyntaxError(err, text, path) {
|
|
|
4666
4669
|
|
|
4667
4670
|
// CLI entry point (invoked when eyeling.js is run directly)
|
|
4668
4671
|
function readTextFromStdinSync() {
|
|
4669
|
-
const fs = require('node:fs');
|
|
4670
4672
|
return fs.readFileSync(0, { encoding: 'utf8' });
|
|
4671
4673
|
}
|
|
4672
4674
|
|
|
@@ -4689,10 +4691,374 @@ function __readInputSourceSync(sourceLabel) {
|
|
|
4689
4691
|
return txt;
|
|
4690
4692
|
}
|
|
4691
4693
|
|
|
4692
|
-
const fs = require('node:fs');
|
|
4693
4694
|
return fs.readFileSync(sourceLabel, { encoding: 'utf8' });
|
|
4694
4695
|
}
|
|
4695
4696
|
|
|
4697
|
+
|
|
4698
|
+
const RDF_MESSAGE_VERSION_RE = /^\s*(?:@version|VERSION)\s+(["'])(?:1\.1|1\.2|1\.2-basic)-messages\1\s*\.?\s*(?:#.*)?$/im;
|
|
4699
|
+
const RDF_MESSAGE_VERSION_LINE_RE = /^\s*(?:@version|VERSION)\s+(["'])(?:1\.1|1\.2|1\.2-basic)-messages\1\s*\.?\s*(?:#.*)?$/i;
|
|
4700
|
+
const RDF_DIRECTIVE_LINE_RE = /^\s*(?:@?(?:prefix|base)\b|PREFIX\b|BASE\b)/i;
|
|
4701
|
+
const RDF_MESSAGE_DELIMITER_LINE_RE = /^\s*(?:MESSAGE\b|@message\s*\.?)\s*(?:#.*)?$/i;
|
|
4702
|
+
const LOG_NAME_OF_IRI = '<http://www.w3.org/2000/10/swap/log#nameOf>';
|
|
4703
|
+
const RDF_TYPE_IRI = '<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>';
|
|
4704
|
+
const XSD_INTEGER_IRI = '<http://www.w3.org/2001/XMLSchema#integer>';
|
|
4705
|
+
const EYMSG_NS = 'https://eyereasoner.github.io/eyeling/vocab/message#';
|
|
4706
|
+
const EYMSG_IRIS = Object.freeze({
|
|
4707
|
+
RDFMessageStream: `<${EYMSG_NS}RDFMessageStream>`,
|
|
4708
|
+
MessageEnvelope: `<${EYMSG_NS}MessageEnvelope>`,
|
|
4709
|
+
envelope: `<${EYMSG_NS}envelope>`,
|
|
4710
|
+
firstEnvelope: `<${EYMSG_NS}firstEnvelope>`,
|
|
4711
|
+
lastEnvelope: `<${EYMSG_NS}lastEnvelope>`,
|
|
4712
|
+
orderedEnvelopes: `<${EYMSG_NS}orderedEnvelopes>`,
|
|
4713
|
+
offset: `<${EYMSG_NS}offset>`,
|
|
4714
|
+
payloadGraph: `<${EYMSG_NS}payloadGraph>`,
|
|
4715
|
+
payloadKind: `<${EYMSG_NS}payloadKind>`,
|
|
4716
|
+
empty: `<${EYMSG_NS}empty>`,
|
|
4717
|
+
nonEmpty: `<${EYMSG_NS}nonEmpty>`,
|
|
4718
|
+
});
|
|
4719
|
+
|
|
4720
|
+
function simpleHashText(s) {
|
|
4721
|
+
let h = 0x811c9dc5;
|
|
4722
|
+
const text = String(s || '');
|
|
4723
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
4724
|
+
h ^= text.charCodeAt(i);
|
|
4725
|
+
h = Math.imul(h, 0x01000193) >>> 0;
|
|
4726
|
+
}
|
|
4727
|
+
return h.toString(16).padStart(8, '0');
|
|
4728
|
+
}
|
|
4729
|
+
|
|
4730
|
+
function __isLocalPathSource(sourceLabel) {
|
|
4731
|
+
return typeof sourceLabel === 'string' && sourceLabel !== '<stdin>' && !/^(https?:|file:\/\/)/i.test(sourceLabel);
|
|
4732
|
+
}
|
|
4733
|
+
|
|
4734
|
+
function __localPathForSource(sourceLabel) {
|
|
4735
|
+
if (__isLocalPathSource(sourceLabel)) return sourceLabel;
|
|
4736
|
+
if (typeof sourceLabel === 'string' && /^file:\/\//i.test(sourceLabel)) return fileURLToPath(sourceLabel);
|
|
4737
|
+
return null;
|
|
4738
|
+
}
|
|
4739
|
+
|
|
4740
|
+
function __sourceLooksLikeRdfMessageLogSync(sourceLabel) {
|
|
4741
|
+
const filePath = __localPathForSource(sourceLabel);
|
|
4742
|
+
if (filePath) {
|
|
4743
|
+
const fd = fs.openSync(filePath, 'r');
|
|
4744
|
+
try {
|
|
4745
|
+
const buf = Buffer.allocUnsafe(64 * 1024);
|
|
4746
|
+
const n = fs.readSync(fd, buf, 0, buf.length, 0);
|
|
4747
|
+
return RDF_MESSAGE_VERSION_RE.test(buf.toString('utf8', 0, n));
|
|
4748
|
+
} finally {
|
|
4749
|
+
fs.closeSync(fd);
|
|
4750
|
+
}
|
|
4751
|
+
}
|
|
4752
|
+
return RDF_MESSAGE_VERSION_RE.test(__readInputSourceSync(sourceLabel));
|
|
4753
|
+
}
|
|
4754
|
+
|
|
4755
|
+
function stripRdfDirectiveLines(text) {
|
|
4756
|
+
return String(text || '')
|
|
4757
|
+
.split(/(?<=\r\n|\n|\r)/)
|
|
4758
|
+
.filter((line) => !RDF_DIRECTIVE_LINE_RE.test(line) && !RDF_MESSAGE_VERSION_LINE_RE.test(line))
|
|
4759
|
+
.join('');
|
|
4760
|
+
}
|
|
4761
|
+
|
|
4762
|
+
function hasRdfPayload(text) {
|
|
4763
|
+
return String(text || '')
|
|
4764
|
+
.split(/\r\n|\n|\r/)
|
|
4765
|
+
.some((line) => {
|
|
4766
|
+
const trimmed = line.replace(/#.*$/g, '').trim();
|
|
4767
|
+
return trimmed && !RDF_DIRECTIVE_LINE_RE.test(trimmed) && !RDF_MESSAGE_VERSION_LINE_RE.test(trimmed);
|
|
4768
|
+
});
|
|
4769
|
+
}
|
|
4770
|
+
|
|
4771
|
+
function addRdfDirective(directives, seen, line) {
|
|
4772
|
+
if (!RDF_DIRECTIVE_LINE_RE.test(line)) return;
|
|
4773
|
+
const key = line.trim();
|
|
4774
|
+
if (!key || seen.has(key)) return;
|
|
4775
|
+
seen.add(key);
|
|
4776
|
+
directives.push(line.endsWith('\n') || line.endsWith('\r') ? line : line + '\n');
|
|
4777
|
+
}
|
|
4778
|
+
|
|
4779
|
+
function normalizeStreamingPayloadChunk(chunk, directives) {
|
|
4780
|
+
const prelude = directives.join('');
|
|
4781
|
+
const normalized = normalizeRdfCompatibility(prelude + String(chunk || ''));
|
|
4782
|
+
return stripRdfDirectiveLines(normalized).trim();
|
|
4783
|
+
}
|
|
4784
|
+
|
|
4785
|
+
function buildSingleMessageReplayDocument({ sourceLabel, messageIndex, chunk, directives }) {
|
|
4786
|
+
const hash = simpleHashText(sourceLabel || '<stream>');
|
|
4787
|
+
const base = `urn:eyeling:message-stream:${hash}`;
|
|
4788
|
+
const padded = String(messageIndex).padStart(6, '0');
|
|
4789
|
+
const stream = `<${base}#stream>`;
|
|
4790
|
+
const envelope = `<${base}#m${padded}>`;
|
|
4791
|
+
const payload = `<${base}#m${padded}/payload>`;
|
|
4792
|
+
const body = normalizeStreamingPayloadChunk(chunk, directives);
|
|
4793
|
+
const hasBody = hasRdfPayload(body);
|
|
4794
|
+
const out = [];
|
|
4795
|
+
|
|
4796
|
+
out.push(...directives.map((line) => line.trim()).filter(Boolean));
|
|
4797
|
+
out.push(`${stream} ${RDF_TYPE_IRI} ${EYMSG_IRIS.RDFMessageStream} .`);
|
|
4798
|
+
out.push(`${stream} ${EYMSG_IRIS.envelope} ${envelope} .`);
|
|
4799
|
+
out.push(`${stream} ${EYMSG_IRIS.orderedEnvelopes} (${envelope}) .`);
|
|
4800
|
+
out.push(`${stream} ${EYMSG_IRIS.firstEnvelope} ${envelope} .`);
|
|
4801
|
+
out.push(`${stream} ${EYMSG_IRIS.lastEnvelope} ${envelope} .`);
|
|
4802
|
+
out.push(`${envelope} ${RDF_TYPE_IRI} ${EYMSG_IRIS.MessageEnvelope} .`);
|
|
4803
|
+
out.push(`${envelope} ${EYMSG_IRIS.offset} "${messageIndex}"^^${XSD_INTEGER_IRI} .`);
|
|
4804
|
+
out.push(`${envelope} ${EYMSG_IRIS.payloadKind} ${hasBody ? EYMSG_IRIS.nonEmpty : EYMSG_IRIS.empty} .`);
|
|
4805
|
+
if (hasBody) {
|
|
4806
|
+
out.push(`${envelope} ${EYMSG_IRIS.payloadGraph} ${payload} .`);
|
|
4807
|
+
out.push(`${payload} ${LOG_NAME_OF_IRI} {`);
|
|
4808
|
+
out.push(body);
|
|
4809
|
+
out.push(`} .`);
|
|
4810
|
+
}
|
|
4811
|
+
return out.join('\n') + '\n';
|
|
4812
|
+
}
|
|
4813
|
+
|
|
4814
|
+
function forEachRdfMessageChunkInText(text, onMessage) {
|
|
4815
|
+
const directives = [];
|
|
4816
|
+
const seenDirectives = new Set();
|
|
4817
|
+
let chunk = '';
|
|
4818
|
+
let messageIndex = 1;
|
|
4819
|
+
let sawVersion = false;
|
|
4820
|
+
let sawDelimiter = false;
|
|
4821
|
+
|
|
4822
|
+
function emit() {
|
|
4823
|
+
onMessage({ messageIndex, chunk, directives: directives.slice() });
|
|
4824
|
+
messageIndex += 1;
|
|
4825
|
+
chunk = '';
|
|
4826
|
+
}
|
|
4827
|
+
|
|
4828
|
+
const lines = String(text || '').match(/.*(?:\r\n|\n|\r)|.+$/g) || [];
|
|
4829
|
+
for (const line of lines) {
|
|
4830
|
+
if (RDF_MESSAGE_VERSION_LINE_RE.test(line)) {
|
|
4831
|
+
sawVersion = true;
|
|
4832
|
+
continue;
|
|
4833
|
+
}
|
|
4834
|
+
if (RDF_MESSAGE_DELIMITER_LINE_RE.test(line)) {
|
|
4835
|
+
emit();
|
|
4836
|
+
sawDelimiter = true;
|
|
4837
|
+
continue;
|
|
4838
|
+
}
|
|
4839
|
+
addRdfDirective(directives, seenDirectives, line);
|
|
4840
|
+
chunk += line;
|
|
4841
|
+
}
|
|
4842
|
+
if (!sawVersion) throw new Error('not an RDF Message Log: missing VERSION "*-messages" directive');
|
|
4843
|
+
if (sawDelimiter || hasRdfPayload(chunk)) emit();
|
|
4844
|
+
}
|
|
4845
|
+
|
|
4846
|
+
function forEachLineInFileSync(filePath, onLine) {
|
|
4847
|
+
const fd = fs.openSync(filePath, 'r');
|
|
4848
|
+
const decoder = new TextDecoder('utf8');
|
|
4849
|
+
const buf = Buffer.allocUnsafe(64 * 1024);
|
|
4850
|
+
let carry = '';
|
|
4851
|
+
try {
|
|
4852
|
+
for (;;) {
|
|
4853
|
+
const n = fs.readSync(fd, buf, 0, buf.length, null);
|
|
4854
|
+
if (n === 0) break;
|
|
4855
|
+
carry += decoder.decode(buf.subarray(0, n), { stream: true });
|
|
4856
|
+
for (;;) {
|
|
4857
|
+
const m = /\r\n|\n|\r/.exec(carry);
|
|
4858
|
+
if (!m) break;
|
|
4859
|
+
const end = m.index + m[0].length;
|
|
4860
|
+
onLine(carry.slice(0, end));
|
|
4861
|
+
carry = carry.slice(end);
|
|
4862
|
+
}
|
|
4863
|
+
}
|
|
4864
|
+
carry += decoder.decode();
|
|
4865
|
+
if (carry) onLine(carry);
|
|
4866
|
+
} finally {
|
|
4867
|
+
fs.closeSync(fd);
|
|
4868
|
+
}
|
|
4869
|
+
}
|
|
4870
|
+
|
|
4871
|
+
function forEachRdfMessageChunkInFileSync(filePath, onMessage) {
|
|
4872
|
+
const directives = [];
|
|
4873
|
+
const seenDirectives = new Set();
|
|
4874
|
+
let chunk = '';
|
|
4875
|
+
let messageIndex = 1;
|
|
4876
|
+
let sawVersion = false;
|
|
4877
|
+
let sawDelimiter = false;
|
|
4878
|
+
|
|
4879
|
+
function emit() {
|
|
4880
|
+
onMessage({ messageIndex, chunk, directives: directives.slice() });
|
|
4881
|
+
messageIndex += 1;
|
|
4882
|
+
chunk = '';
|
|
4883
|
+
}
|
|
4884
|
+
|
|
4885
|
+
forEachLineInFileSync(filePath, (line) => {
|
|
4886
|
+
if (RDF_MESSAGE_VERSION_LINE_RE.test(line)) {
|
|
4887
|
+
sawVersion = true;
|
|
4888
|
+
return;
|
|
4889
|
+
}
|
|
4890
|
+
if (RDF_MESSAGE_DELIMITER_LINE_RE.test(line)) {
|
|
4891
|
+
emit();
|
|
4892
|
+
sawDelimiter = true;
|
|
4893
|
+
return;
|
|
4894
|
+
}
|
|
4895
|
+
addRdfDirective(directives, seenDirectives, line);
|
|
4896
|
+
chunk += line;
|
|
4897
|
+
});
|
|
4898
|
+
|
|
4899
|
+
if (!sawVersion) throw new Error('not an RDF Message Log: missing VERSION "*-messages" directive');
|
|
4900
|
+
if (sawDelimiter || hasRdfPayload(chunk)) emit();
|
|
4901
|
+
}
|
|
4902
|
+
|
|
4903
|
+
|
|
4904
|
+
function __forEachRdfMessageChunkSync(sourceLabel, onMessage) {
|
|
4905
|
+
const filePath = __localPathForSource(sourceLabel);
|
|
4906
|
+
if (filePath) {
|
|
4907
|
+
forEachRdfMessageChunkInFileSync(filePath, onMessage);
|
|
4908
|
+
return;
|
|
4909
|
+
}
|
|
4910
|
+
forEachRdfMessageChunkInText(__readInputSourceSync(sourceLabel), onMessage);
|
|
4911
|
+
}
|
|
4912
|
+
|
|
4913
|
+
function factsContainOutputStrings(triplesForOutput) {
|
|
4914
|
+
const LOG_OUTPUT_STRING = 'http://www.w3.org/2000/10/swap/log#outputString';
|
|
4915
|
+
return (
|
|
4916
|
+
Array.isArray(triplesForOutput) &&
|
|
4917
|
+
triplesForOutput.some(
|
|
4918
|
+
(tr) => tr && tr.p && tr.p.constructor && tr.p.constructor.name === 'Iri' && tr.p.value === LOG_OUTPUT_STRING,
|
|
4919
|
+
)
|
|
4920
|
+
);
|
|
4921
|
+
}
|
|
4922
|
+
|
|
4923
|
+
function programMayProduceOutputStrings(topLevelTriples, forwardRules, logQueryRules) {
|
|
4924
|
+
const hasOutputStringPredicate = (trs) => factsContainOutputStrings(trs);
|
|
4925
|
+
if (hasOutputStringPredicate(topLevelTriples)) return true;
|
|
4926
|
+
if (Array.isArray(forwardRules) && forwardRules.some((r) => hasOutputStringPredicate(r && r.conclusion))) return true;
|
|
4927
|
+
if (Array.isArray(logQueryRules) && logQueryRules.some((r) => hasOutputStringPredicate(r && r.conclusion))) return true;
|
|
4928
|
+
return false;
|
|
4929
|
+
}
|
|
4930
|
+
|
|
4931
|
+
function runParsedDocumentOnce(mergedDocument, { rdfMode = false, outputPrefixes = null } = {}) {
|
|
4932
|
+
const prefixes = mergedDocument.prefixes;
|
|
4933
|
+
const triples = mergedDocument.triples;
|
|
4934
|
+
const frules = mergedDocument.frules;
|
|
4935
|
+
const brules = mergedDocument.brules;
|
|
4936
|
+
const qrules = mergedDocument.logQueryRules;
|
|
4937
|
+
|
|
4938
|
+
engine.materializeRdfLists(triples, frules.concat(qrules || []), brules);
|
|
4939
|
+
const facts = triples.slice();
|
|
4940
|
+
const hasQueries = Array.isArray(qrules) && qrules.length;
|
|
4941
|
+
const mayAutoRenderOutputStrings = programMayProduceOutputStrings(triples, frules, qrules);
|
|
4942
|
+
|
|
4943
|
+
let derived = [];
|
|
4944
|
+
let outTriples = [];
|
|
4945
|
+
if (hasQueries) {
|
|
4946
|
+
const res = engine.forwardChainAndCollectLogQueryConclusions(facts, frules, brules, qrules, { prefixes });
|
|
4947
|
+
derived = res.derived;
|
|
4948
|
+
outTriples = res.queryTriples;
|
|
4949
|
+
} else {
|
|
4950
|
+
const skipDerivedCollection = mayAutoRenderOutputStrings;
|
|
4951
|
+
derived = engine.forwardChain(facts, frules, brules, null, {
|
|
4952
|
+
captureExplanations: false,
|
|
4953
|
+
collectDerived: !skipDerivedCollection,
|
|
4954
|
+
prefixes,
|
|
4955
|
+
});
|
|
4956
|
+
outTriples = skipDerivedCollection ? [] : derived.map((df) => df.fact);
|
|
4957
|
+
}
|
|
4958
|
+
|
|
4959
|
+
const renderedOutputTriples = hasQueries ? outTriples : facts;
|
|
4960
|
+
if (factsContainOutputStrings(renderedOutputTriples)) {
|
|
4961
|
+
process.stdout.write(engine.collectOutputStringsFromFacts(renderedOutputTriples, prefixes));
|
|
4962
|
+
return;
|
|
4963
|
+
}
|
|
4964
|
+
|
|
4965
|
+
const outPrefixEnv = outputPrefixes || prefixes;
|
|
4966
|
+
if (rdfMode) {
|
|
4967
|
+
for (const tr of outTriples) console.log(engine.tripleToRdfCompatible(tr, outPrefixEnv));
|
|
4968
|
+
} else if (hasQueries) {
|
|
4969
|
+
const bodyText = engine.prettyPrintQueryTriples(outTriples, outPrefixEnv);
|
|
4970
|
+
if (bodyText) process.stdout.write(String(bodyText).replace(/\s*$/g, '') + '\n');
|
|
4971
|
+
} else {
|
|
4972
|
+
for (const df of derived) console.log(engine.tripleToN3(df.fact, outPrefixEnv));
|
|
4973
|
+
}
|
|
4974
|
+
}
|
|
4975
|
+
|
|
4976
|
+
function runStreamMessagesMode(sourceLabels, { rdfMode }) {
|
|
4977
|
+
const ordinarySourceLabels = [];
|
|
4978
|
+
const messageSourceLabels = [];
|
|
4979
|
+
|
|
4980
|
+
for (const sourceLabel of sourceLabels) {
|
|
4981
|
+
try {
|
|
4982
|
+
if (__sourceLooksLikeRdfMessageLogSync(sourceLabel)) messageSourceLabels.push(sourceLabel);
|
|
4983
|
+
else ordinarySourceLabels.push(sourceLabel);
|
|
4984
|
+
} catch (e) {
|
|
4985
|
+
console.error(`Error reading source ${JSON.stringify(sourceLabel)}: ${e && e.message ? e.message : String(e)}`);
|
|
4986
|
+
process.exit(1);
|
|
4987
|
+
}
|
|
4988
|
+
}
|
|
4989
|
+
|
|
4990
|
+
if (!messageSourceLabels.length) {
|
|
4991
|
+
console.error('Error: --stream-messages did not find any RDF Message Log input.');
|
|
4992
|
+
process.exit(1);
|
|
4993
|
+
}
|
|
4994
|
+
|
|
4995
|
+
const programSources = [];
|
|
4996
|
+
for (const sourceLabel of ordinarySourceLabels) {
|
|
4997
|
+
let text;
|
|
4998
|
+
try {
|
|
4999
|
+
text = __readInputSourceSync(sourceLabel);
|
|
5000
|
+
} catch (e) {
|
|
5001
|
+
if (sourceLabel === '<stdin>') console.error(`Error reading stdin: ${e.message}`);
|
|
5002
|
+
else console.error(`Error reading source ${JSON.stringify(sourceLabel)}: ${e.message}`);
|
|
5003
|
+
process.exit(1);
|
|
5004
|
+
}
|
|
5005
|
+
|
|
5006
|
+
try {
|
|
5007
|
+
programSources.push(
|
|
5008
|
+
parseN3Text(text, {
|
|
5009
|
+
baseIri: __sourceLabelToBaseIri(sourceLabel),
|
|
5010
|
+
label: sourceLabel,
|
|
5011
|
+
keepSourceArtifacts: false,
|
|
5012
|
+
sourceLocations: false,
|
|
5013
|
+
rdf: rdfMode,
|
|
5014
|
+
}),
|
|
5015
|
+
);
|
|
5016
|
+
} catch (e) {
|
|
5017
|
+
if (e && e.name === 'N3SyntaxError') {
|
|
5018
|
+
console.error(formatN3SyntaxError(e, text, sourceLabel));
|
|
5019
|
+
process.exit(1);
|
|
5020
|
+
}
|
|
5021
|
+
throw e;
|
|
5022
|
+
}
|
|
5023
|
+
}
|
|
5024
|
+
|
|
5025
|
+
const fullIriPrefixes = new PrefixEnv({});
|
|
5026
|
+
for (const messageSourceLabel of messageSourceLabels) {
|
|
5027
|
+
try {
|
|
5028
|
+
__forEachRdfMessageChunkSync(messageSourceLabel, ({ messageIndex, chunk, directives }) => {
|
|
5029
|
+
const messageText = buildSingleMessageReplayDocument({
|
|
5030
|
+
sourceLabel: messageSourceLabel,
|
|
5031
|
+
messageIndex,
|
|
5032
|
+
chunk,
|
|
5033
|
+
directives,
|
|
5034
|
+
});
|
|
5035
|
+
let messageDoc;
|
|
5036
|
+
try {
|
|
5037
|
+
messageDoc = parseN3Text(messageText, {
|
|
5038
|
+
baseIri: `${__sourceLabelToBaseIri(messageSourceLabel)}#message-${messageIndex}`,
|
|
5039
|
+
label: `${messageSourceLabel}#message-${messageIndex}`,
|
|
5040
|
+
keepSourceArtifacts: false,
|
|
5041
|
+
sourceLocations: false,
|
|
5042
|
+
rdf: false,
|
|
5043
|
+
});
|
|
5044
|
+
} catch (e) {
|
|
5045
|
+
if (e && e.name === 'N3SyntaxError') {
|
|
5046
|
+
console.error(formatN3SyntaxError(e, messageText, `${messageSourceLabel}#message-${messageIndex}`));
|
|
5047
|
+
process.exit(1);
|
|
5048
|
+
}
|
|
5049
|
+
throw e;
|
|
5050
|
+
}
|
|
5051
|
+
|
|
5052
|
+
const merged = mergeParsedDocuments(programSources.concat([messageDoc]));
|
|
5053
|
+
runParsedDocumentOnce(merged, { rdfMode, outputPrefixes: fullIriPrefixes });
|
|
5054
|
+
});
|
|
5055
|
+
} catch (e) {
|
|
5056
|
+
console.error(`Error streaming RDF Message Log ${JSON.stringify(messageSourceLabel)}: ${e && e.message ? e.message : String(e)}`);
|
|
5057
|
+
process.exit(1);
|
|
5058
|
+
}
|
|
5059
|
+
}
|
|
5060
|
+
}
|
|
5061
|
+
|
|
4696
5062
|
function main() {
|
|
4697
5063
|
// Drop "node" and script name; keep only user-provided args
|
|
4698
5064
|
// Expand combined short options: -pt == -p -t
|
|
@@ -4723,6 +5089,7 @@ function main() {
|
|
|
4723
5089
|
` -h, --help Show this help and exit.\n` +
|
|
4724
5090
|
` -p, --proof Enable proof explanations.\n` +
|
|
4725
5091
|
` -r, --rdf Enable RDF/TriG input/output compatibility.\n` +
|
|
5092
|
+
` --stream-messages Process RDF Message Logs one message at a time under -r.\n` +
|
|
4726
5093
|
` -s, --super-restricted Disable all builtins except => and <=.\n` +
|
|
4727
5094
|
` -t, --stream Stream derived triples as soon as they are derived.\n` +
|
|
4728
5095
|
` -v, --version Print version and exit.\n`;
|
|
@@ -4764,6 +5131,7 @@ function main() {
|
|
|
4764
5131
|
|
|
4765
5132
|
const showAst = argv.includes('--ast') || argv.includes('-a');
|
|
4766
5133
|
const streamMode = argv.includes('--stream') || argv.includes('-t');
|
|
5134
|
+
const streamMessagesMode = argv.includes('--stream-messages');
|
|
4767
5135
|
const rdfMode = argv.includes('--rdf') || argv.includes('-r');
|
|
4768
5136
|
|
|
4769
5137
|
// --enforce-https: rewrite http:// -> https:// for log dereferencing builtins
|
|
@@ -4786,6 +5154,26 @@ function main() {
|
|
|
4786
5154
|
if (typeof engine.setSuperRestrictedMode === 'function') engine.setSuperRestrictedMode(true);
|
|
4787
5155
|
}
|
|
4788
5156
|
|
|
5157
|
+
|
|
5158
|
+
if (streamMessagesMode) {
|
|
5159
|
+
if (!rdfMode) {
|
|
5160
|
+
console.error('Error: --stream-messages requires -r/--rdf.');
|
|
5161
|
+
process.exit(1);
|
|
5162
|
+
}
|
|
5163
|
+
if (showAst) {
|
|
5164
|
+
console.error('Error: --stream-messages cannot be combined with --ast.');
|
|
5165
|
+
process.exit(1);
|
|
5166
|
+
}
|
|
5167
|
+
if (streamMode) {
|
|
5168
|
+
console.error('Error: --stream-messages cannot be combined with --stream.');
|
|
5169
|
+
process.exit(1);
|
|
5170
|
+
}
|
|
5171
|
+
if (engine.getProofCommentsEnabled()) {
|
|
5172
|
+
console.error('Error: --stream-messages currently does not support proof output.');
|
|
5173
|
+
process.exit(1);
|
|
5174
|
+
}
|
|
5175
|
+
}
|
|
5176
|
+
|
|
4789
5177
|
// Positional args (one or more N3 sources).
|
|
4790
5178
|
const useImplicitStdin = positional.length === 0 && !process.stdin.isTTY;
|
|
4791
5179
|
if (positional.length === 0 && !useImplicitStdin) {
|
|
@@ -4809,6 +5197,11 @@ function main() {
|
|
|
4809
5197
|
process.exit(1);
|
|
4810
5198
|
}
|
|
4811
5199
|
|
|
5200
|
+
if (streamMessagesMode) {
|
|
5201
|
+
runStreamMessagesMode(sourceLabels, { rdfMode });
|
|
5202
|
+
return;
|
|
5203
|
+
}
|
|
5204
|
+
|
|
4812
5205
|
const parsedSources = [];
|
|
4813
5206
|
for (const sourceLabel of sourceLabels) {
|
|
4814
5207
|
let text;
|