eyeling 1.28.9 → 1.29.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 +60 -1
- package/dist/browser/eyeling.browser.js +915 -0
- package/dist/browser/index.mjs +10 -0
- package/eyeling.js +915 -0
- package/index.d.ts +59 -0
- package/index.js +17 -0
- package/lib/cli.js +102 -0
- package/lib/engine.js +120 -0
- package/lib/entry.js +4 -0
- package/lib/rdfjs.js +1 -0
- package/lib/store.js +685 -0
- package/package.json +8 -3
- package/test/store.test.js +138 -0
- package/tools/bundle.js +10 -0
package/index.d.ts
CHANGED
|
@@ -151,6 +151,14 @@ declare module 'eyeling' {
|
|
|
151
151
|
document?: EyelingAstBundle;
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
export interface StoreOptions {
|
|
155
|
+
name?: string;
|
|
156
|
+
clear?: boolean;
|
|
157
|
+
path?: string;
|
|
158
|
+
type?: 'memory' | 'persistent';
|
|
159
|
+
backend?: 'memory' | 'level' | 'indexeddb';
|
|
160
|
+
}
|
|
161
|
+
|
|
154
162
|
export interface ReasonOptions {
|
|
155
163
|
proof?: boolean;
|
|
156
164
|
proofComments?: boolean;
|
|
@@ -158,6 +166,9 @@ declare module 'eyeling' {
|
|
|
158
166
|
args?: string[];
|
|
159
167
|
maxBuffer?: number;
|
|
160
168
|
builtinModules?: string | string[];
|
|
169
|
+
store?: string | StoreOptions;
|
|
170
|
+
storePath?: string;
|
|
171
|
+
storeClear?: boolean;
|
|
161
172
|
}
|
|
162
173
|
|
|
163
174
|
export interface BuiltinRegistrationContext {
|
|
@@ -183,6 +194,9 @@ declare module 'eyeling' {
|
|
|
183
194
|
dataFactory?: RdfJsDataFactory | null;
|
|
184
195
|
skipUnsupportedRdfJs?: boolean;
|
|
185
196
|
builtinModules?: string | string[];
|
|
197
|
+
store?: string | StoreOptions;
|
|
198
|
+
storePath?: string;
|
|
199
|
+
storeClear?: boolean;
|
|
186
200
|
onDerived?: (item: { triple: string; quad?: RdfJsQuad; quads?: RdfJsQuad[]; df: any }) => void;
|
|
187
201
|
}
|
|
188
202
|
|
|
@@ -198,10 +212,45 @@ declare module 'eyeling' {
|
|
|
198
212
|
queryQuads?: RdfJsQuad[];
|
|
199
213
|
}
|
|
200
214
|
|
|
215
|
+
export interface FactStore {
|
|
216
|
+
add(triple: EyelingTriple, kind?: 'explicit' | 'inferred'): Promise<boolean>;
|
|
217
|
+
has(triple: EyelingTriple): Promise<boolean>;
|
|
218
|
+
kindOf?(triple: EyelingTriple): Promise<number>;
|
|
219
|
+
match(s?: EyelingTerm | null, p?: EyelingTerm | null, o?: EyelingTerm | null): AsyncIterable<EyelingTriple>;
|
|
220
|
+
batchAdd?(triples: Iterable<EyelingTriple>, kind?: 'explicit' | 'inferred'): Promise<number>;
|
|
221
|
+
clear?(): Promise<void>;
|
|
222
|
+
close?(): Promise<void>;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export class MemoryFactStore implements FactStore {
|
|
226
|
+
constructor();
|
|
227
|
+
add(triple: EyelingTriple, kind?: 'explicit' | 'inferred'): Promise<boolean>;
|
|
228
|
+
has(triple: EyelingTriple): Promise<boolean>;
|
|
229
|
+
kindOf(triple: EyelingTriple): Promise<number>;
|
|
230
|
+
match(s?: EyelingTerm | null, p?: EyelingTerm | null, o?: EyelingTerm | null): AsyncIterable<EyelingTriple>;
|
|
231
|
+
batchAdd(triples: Iterable<EyelingTriple>, kind?: 'explicit' | 'inferred'): Promise<number>;
|
|
232
|
+
clear(): Promise<void>;
|
|
233
|
+
close(): Promise<void>;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export class PersistentFactStore implements FactStore {
|
|
237
|
+
add(triple: EyelingTriple, kind?: 'explicit' | 'inferred'): Promise<boolean>;
|
|
238
|
+
has(triple: EyelingTriple): Promise<boolean>;
|
|
239
|
+
kindOf(triple: EyelingTriple): Promise<number>;
|
|
240
|
+
match(s?: EyelingTerm | null, p?: EyelingTerm | null, o?: EyelingTerm | null): AsyncIterable<EyelingTriple>;
|
|
241
|
+
batchAdd(triples: Iterable<EyelingTriple>, kind?: 'explicit' | 'inferred'): Promise<number>;
|
|
242
|
+
clear(): Promise<void>;
|
|
243
|
+
close(): Promise<void>;
|
|
244
|
+
}
|
|
245
|
+
|
|
201
246
|
export function reason(
|
|
202
247
|
opts: ReasonOptions,
|
|
203
248
|
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
204
249
|
): string;
|
|
250
|
+
export function runAsync(
|
|
251
|
+
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
252
|
+
opts?: ReasonStreamOptions,
|
|
253
|
+
): Promise<ReasonStreamResult & { store?: FactStore }>;
|
|
205
254
|
export function reasonStream(
|
|
206
255
|
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
207
256
|
opts?: ReasonStreamOptions,
|
|
@@ -213,6 +262,7 @@ declare module 'eyeling' {
|
|
|
213
262
|
|
|
214
263
|
export const INFERENCE_FUSE_EXIT_CODE: 65;
|
|
215
264
|
export const rdfjs: RdfJsDataFactory;
|
|
265
|
+
export function createFactStore(options?: string | StoreOptions | null): Promise<FactStore>;
|
|
216
266
|
export function registerBuiltin(iri: string, handler: BuiltinHandler): BuiltinHandler;
|
|
217
267
|
export function unregisterBuiltin(iri: string): boolean;
|
|
218
268
|
export function registerBuiltinModule(mod: any, origin?: string): boolean;
|
|
@@ -230,7 +280,13 @@ declare module 'eyeling/browser' {
|
|
|
230
280
|
export type ReasonStreamOptions = import('eyeling').ReasonStreamOptions;
|
|
231
281
|
export type ReasonStreamResult = import('eyeling').ReasonStreamResult;
|
|
232
282
|
export type BuiltinHandler = import('eyeling').BuiltinHandler;
|
|
283
|
+
export type StoreOptions = import('eyeling').StoreOptions;
|
|
284
|
+
export type FactStore = import('eyeling').FactStore;
|
|
233
285
|
|
|
286
|
+
export function runAsync(
|
|
287
|
+
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
288
|
+
opts?: ReasonStreamOptions,
|
|
289
|
+
): Promise<ReasonStreamResult & { store?: FactStore }>;
|
|
234
290
|
export function reasonStream(
|
|
235
291
|
input: string | RdfJsReasonInput | EyelingAstBundle | N3SourceListInput,
|
|
236
292
|
opts?: ReasonStreamOptions,
|
|
@@ -242,6 +298,7 @@ declare module 'eyeling/browser' {
|
|
|
242
298
|
|
|
243
299
|
export const INFERENCE_FUSE_EXIT_CODE: 65;
|
|
244
300
|
export const rdfjs: RdfJsDataFactory;
|
|
301
|
+
export function createFactStore(options?: string | StoreOptions | null): Promise<FactStore>;
|
|
245
302
|
export function registerBuiltin(iri: string, handler: BuiltinHandler): BuiltinHandler;
|
|
246
303
|
export function unregisterBuiltin(iri: string): boolean;
|
|
247
304
|
export function registerBuiltinModule(mod: any, origin?: string): boolean;
|
|
@@ -249,10 +306,12 @@ declare module 'eyeling/browser' {
|
|
|
249
306
|
|
|
250
307
|
const eyeling: {
|
|
251
308
|
readonly version: string;
|
|
309
|
+
runAsync: typeof runAsync;
|
|
252
310
|
reasonStream: typeof reasonStream;
|
|
253
311
|
reasonRdfJs: typeof reasonRdfJs;
|
|
254
312
|
readonly INFERENCE_FUSE_EXIT_CODE: typeof INFERENCE_FUSE_EXIT_CODE;
|
|
255
313
|
rdfjs: typeof rdfjs;
|
|
314
|
+
createFactStore: typeof createFactStore;
|
|
256
315
|
registerBuiltin: typeof registerBuiltin;
|
|
257
316
|
unregisterBuiltin: typeof unregisterBuiltin;
|
|
258
317
|
registerBuiltinModule: typeof registerBuiltinModule;
|
package/index.js
CHANGED
|
@@ -42,6 +42,15 @@ function reason(opt = {}, input = '') {
|
|
|
42
42
|
|
|
43
43
|
if (opt.rdf) args.push('--rdf');
|
|
44
44
|
|
|
45
|
+
if (typeof opt.store === 'string' && opt.store) args.push('--store', opt.store);
|
|
46
|
+
else if (opt.store && typeof opt.store === 'object') {
|
|
47
|
+
if (opt.store.name) args.push('--store', String(opt.store.name));
|
|
48
|
+
if (opt.store.clear) args.push('--store-clear');
|
|
49
|
+
if (opt.store.path) args.push('--store-path', String(opt.store.path));
|
|
50
|
+
}
|
|
51
|
+
if (opt.storePath) args.push('--store-path', String(opt.storePath));
|
|
52
|
+
if (opt.storeClear) args.push('--store-clear');
|
|
53
|
+
|
|
45
54
|
if (Array.isArray(opt.args)) args.push(...opt.args);
|
|
46
55
|
|
|
47
56
|
const builtinModules = Array.isArray(opt.builtinModules)
|
|
@@ -106,8 +115,13 @@ function reason(opt = {}, input = '') {
|
|
|
106
115
|
}
|
|
107
116
|
}
|
|
108
117
|
|
|
118
|
+
async function runAsync(input = '', opt = {}) {
|
|
119
|
+
return engine.runAsync(input, opt || {});
|
|
120
|
+
}
|
|
121
|
+
|
|
109
122
|
module.exports = {
|
|
110
123
|
reason,
|
|
124
|
+
runAsync,
|
|
111
125
|
reasonStream: bundleApi.reasonStream,
|
|
112
126
|
reasonRdfJs: bundleApi.reasonRdfJs,
|
|
113
127
|
rdfjs: dataFactory,
|
|
@@ -116,6 +130,9 @@ module.exports = {
|
|
|
116
130
|
registerBuiltinModule: engine.registerBuiltinModule,
|
|
117
131
|
loadBuiltinModule: engine.loadBuiltinModule,
|
|
118
132
|
listBuiltinIris: engine.listBuiltinIris,
|
|
133
|
+
createFactStore: engine.createFactStore,
|
|
134
|
+
MemoryFactStore: engine.MemoryFactStore,
|
|
135
|
+
PersistentFactStore: engine.PersistentFactStore,
|
|
119
136
|
};
|
|
120
137
|
|
|
121
138
|
// small interop nicety for ESM default import
|
package/lib/cli.js
CHANGED
|
@@ -710,6 +710,9 @@ async function main() {
|
|
|
710
710
|
` -p, --proof Enable proof explanations.\n` +
|
|
711
711
|
` -r, --rdf Enable RDF/TriG input/output compatibility.\n` +
|
|
712
712
|
` --stream-messages Process RDF Message Logs one message at a time under -r.\n` +
|
|
713
|
+
` --store <name> Use an optional persistent fact store.\n` +
|
|
714
|
+
` --store-clear Clear the named store before this run.\n` +
|
|
715
|
+
` --store-path <dir> Node.js persistent store directory.\n` +
|
|
713
716
|
` -s, --super-restricted Disable all builtins except => and <=.\n` +
|
|
714
717
|
` -t, --stream Stream derived triples as soon as they are derived.\n` +
|
|
715
718
|
` -v, --version Print version and exit.\n`;
|
|
@@ -746,6 +749,35 @@ async function main() {
|
|
|
746
749
|
builtinModules.push(a.slice('--builtin='.length));
|
|
747
750
|
continue;
|
|
748
751
|
}
|
|
752
|
+
if (a === '--store') {
|
|
753
|
+
const next = argv[i + 1];
|
|
754
|
+
if (!next || next.startsWith('-')) {
|
|
755
|
+
console.error('Error: --store expects a store name.');
|
|
756
|
+
process.exit(1);
|
|
757
|
+
}
|
|
758
|
+
argv.__storeName = next;
|
|
759
|
+
i += 1;
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
if (typeof a === 'string' && a.startsWith('--store=')) {
|
|
763
|
+
argv.__storeName = a.slice('--store='.length);
|
|
764
|
+
continue;
|
|
765
|
+
}
|
|
766
|
+
if (a === '--store-path') {
|
|
767
|
+
const next = argv[i + 1];
|
|
768
|
+
if (!next || next.startsWith('-')) {
|
|
769
|
+
console.error('Error: --store-path expects a directory path.');
|
|
770
|
+
process.exit(1);
|
|
771
|
+
}
|
|
772
|
+
argv.__storePath = next;
|
|
773
|
+
i += 1;
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
if (typeof a === 'string' && a.startsWith('--store-path=')) {
|
|
777
|
+
argv.__storePath = a.slice('--store-path='.length);
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
if (a === '--store-clear') continue;
|
|
749
781
|
if (a === '-' || !a.startsWith('-')) positional.push(a);
|
|
750
782
|
}
|
|
751
783
|
|
|
@@ -753,6 +785,9 @@ async function main() {
|
|
|
753
785
|
const streamMode = argv.includes('--stream') || argv.includes('-t');
|
|
754
786
|
const streamMessagesMode = argv.includes('--stream-messages');
|
|
755
787
|
const rdfMode = argv.includes('--rdf') || argv.includes('-r');
|
|
788
|
+
const storeName = argv.__storeName || null;
|
|
789
|
+
const storePath = argv.__storePath || null;
|
|
790
|
+
const storeClear = argv.includes('--store-clear');
|
|
756
791
|
|
|
757
792
|
// --enforce-https: rewrite http:// -> https:// for log dereferencing builtins
|
|
758
793
|
if (argv.includes('--enforce-https') || argv.includes('-e')) {
|
|
@@ -776,6 +811,10 @@ async function main() {
|
|
|
776
811
|
|
|
777
812
|
|
|
778
813
|
if (streamMessagesMode) {
|
|
814
|
+
if (storeName) {
|
|
815
|
+
console.error('Error: --store cannot be combined with --stream-messages yet.');
|
|
816
|
+
process.exit(1);
|
|
817
|
+
}
|
|
779
818
|
if (!rdfMode) {
|
|
780
819
|
console.error('Error: --stream-messages requires -r/--rdf.');
|
|
781
820
|
process.exit(1);
|
|
@@ -931,6 +970,69 @@ function factsContainOutputStrings(triplesForOutput) {
|
|
|
931
970
|
const hasQueries = Array.isArray(qrules) && qrules.length;
|
|
932
971
|
const mayAutoRenderOutputStrings = programMayProduceOutputStrings(triples, frules, qrules);
|
|
933
972
|
|
|
973
|
+
if (storeName) {
|
|
974
|
+
if (streamMode) {
|
|
975
|
+
console.error('Error: --store cannot be combined with --stream yet.');
|
|
976
|
+
process.exit(1);
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
const storeResult = await engine.runAsync(
|
|
980
|
+
{ prefixes, triples, frules, brules, logQueryRules: qrules },
|
|
981
|
+
{
|
|
982
|
+
proof: engine.getProofCommentsEnabled(),
|
|
983
|
+
rdf: rdfMode,
|
|
984
|
+
store: { name: storeName, clear: storeClear, path: storePath || undefined },
|
|
985
|
+
},
|
|
986
|
+
);
|
|
987
|
+
|
|
988
|
+
const storeFacts = storeResult.facts || [];
|
|
989
|
+
const storeDerived = storeResult.derived || [];
|
|
990
|
+
const storeHasQueries = !!storeResult.queryMode;
|
|
991
|
+
const storeOutTriples = storeHasQueries ? (storeResult.queryTriples || []) : (mayAutoRenderOutputStrings && !engine.getProofCommentsEnabled() ? [] : storeDerived.map((df) => df.fact));
|
|
992
|
+
const storeOutDerived = storeHasQueries ? (storeResult.queryDerived || []) : storeDerived;
|
|
993
|
+
const renderedOutputTriples = storeHasQueries ? storeOutTriples : storeFacts;
|
|
994
|
+
|
|
995
|
+
if (factsContainOutputStrings(renderedOutputTriples)) {
|
|
996
|
+
process.stdout.write(engine.collectOutputStringsFromFacts(renderedOutputTriples, prefixes));
|
|
997
|
+
if (storeResult.store && typeof storeResult.store.close === 'function') await storeResult.store.close();
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
if (engine.getProofCommentsEnabled()) {
|
|
1002
|
+
process.stdout.write(engine.renderProofDocument(storeOutDerived, storeDerived.concat(storeOutDerived || []), triples, prefixes, brules));
|
|
1003
|
+
if (storeResult.store && typeof storeResult.store.close === 'function') await storeResult.store.close();
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
let bodyText = '';
|
|
1008
|
+
if (rdfMode) bodyText = storeOutTriples.map((tr) => engine.tripleToRdfCompatible(tr, prefixes)).join('\n');
|
|
1009
|
+
else if (storeHasQueries) bodyText = engine.prettyPrintQueryTriples(storeOutTriples, prefixes);
|
|
1010
|
+
|
|
1011
|
+
let usedPrefixes = prefixes.prefixesUsedForOutput(storeOutTriples);
|
|
1012
|
+
if (rdfMode && bodyText) usedPrefixes = usedPrefixes.filter(([pfx]) => pfx === '' || bodyText.includes(pfx + ':'));
|
|
1013
|
+
|
|
1014
|
+
if (rdfMode && bodyText.includes('<<(')) {
|
|
1015
|
+
console.log('VERSION "1.2"');
|
|
1016
|
+
console.log();
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
for (const [pfx, base] of usedPrefixes) {
|
|
1020
|
+
if (pfx === '') console.log(`@prefix : <${base}> .`);
|
|
1021
|
+
else console.log(`@prefix ${pfx}: <${base}> .`);
|
|
1022
|
+
}
|
|
1023
|
+
if (storeOutTriples.length && usedPrefixes.length) console.log();
|
|
1024
|
+
|
|
1025
|
+
if (bodyText) process.stdout.write(String(bodyText).replace(/\s*$/g, '') + '\n');
|
|
1026
|
+
else {
|
|
1027
|
+
for (const df of storeOutDerived) {
|
|
1028
|
+
console.log(rdfMode ? engine.tripleToRdfCompatible(df.fact, prefixes) : engine.tripleToN3(df.fact, prefixes));
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
if (storeResult.store && typeof storeResult.store.close === 'function') await storeResult.store.close();
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
934
1036
|
if (streamMode && !hasQueries && !mayAutoRenderOutputStrings && !engine.getProofCommentsEnabled()) {
|
|
935
1037
|
const usedInInput = mergedDocument.usedPrefixes instanceof Set ? new Set(mergedDocument.usedPrefixes) : new Set();
|
|
936
1038
|
const outPrefixes = restrictPrefixEnv(prefixes, usedInInput);
|
package/lib/engine.js
CHANGED
|
@@ -97,6 +97,7 @@ const {
|
|
|
97
97
|
getDataFactory,
|
|
98
98
|
internalTripleToRdfJsQuads,
|
|
99
99
|
normalizeParsedReasonerInputSync,
|
|
100
|
+
normalizeParsedReasonerInputAsync,
|
|
100
101
|
normalizeReasonerInputSync,
|
|
101
102
|
normalizeReasonerInputAsync,
|
|
102
103
|
} = require('./rdfjs');
|
|
@@ -105,6 +106,7 @@ const trace = require('./trace');
|
|
|
105
106
|
const { deterministicSkolemIdFromKey } = require('./skolem');
|
|
106
107
|
|
|
107
108
|
const deref = require('./deref');
|
|
109
|
+
const { createFactStore, collectStore, MemoryFactStore, PersistentFactStore } = require('./store');
|
|
108
110
|
|
|
109
111
|
const hasOwn = Object.prototype.hasOwnProperty;
|
|
110
112
|
|
|
@@ -3783,6 +3785,120 @@ function reasonStream(input, opts = {}) {
|
|
|
3783
3785
|
return __out;
|
|
3784
3786
|
}
|
|
3785
3787
|
|
|
3788
|
+
|
|
3789
|
+
async function __parseRunAsyncInput(input, opts) {
|
|
3790
|
+
const {
|
|
3791
|
+
baseIri = null,
|
|
3792
|
+
proof = false,
|
|
3793
|
+
rdf = false,
|
|
3794
|
+
sourceLabel = '<input>',
|
|
3795
|
+
} = opts || {};
|
|
3796
|
+
|
|
3797
|
+
const parsedSourceList = parseN3SourceList(input, { baseIri, rdf: !!rdf, sourceLocations: !!proof });
|
|
3798
|
+
if (parsedSourceList) return parsedSourceList;
|
|
3799
|
+
|
|
3800
|
+
const parsedObject = await normalizeParsedReasonerInputAsync(input);
|
|
3801
|
+
if (parsedObject) {
|
|
3802
|
+
if (baseIri && parsedObject.prefixes && typeof parsedObject.prefixes.setBase === 'function') parsedObject.prefixes.setBase(baseIri);
|
|
3803
|
+
return parsedObject;
|
|
3804
|
+
}
|
|
3805
|
+
|
|
3806
|
+
const n3Text = await normalizeReasonerInputAsync(input);
|
|
3807
|
+
return parseN3Text(n3Text, {
|
|
3808
|
+
baseIri: baseIri || '',
|
|
3809
|
+
label: sourceLabel || '<input>',
|
|
3810
|
+
keepSourceArtifacts: false,
|
|
3811
|
+
sourceLocations: !!proof,
|
|
3812
|
+
rdf: !!rdf,
|
|
3813
|
+
});
|
|
3814
|
+
}
|
|
3815
|
+
|
|
3816
|
+
function __withoutStoreOptions(opts) {
|
|
3817
|
+
const out = { ...(opts || {}) };
|
|
3818
|
+
delete out.store;
|
|
3819
|
+
delete out.storePath;
|
|
3820
|
+
delete out.storeClear;
|
|
3821
|
+
return out;
|
|
3822
|
+
}
|
|
3823
|
+
|
|
3824
|
+
function __normalizeStoreOption(opts) {
|
|
3825
|
+
const cfg = opts && opts.store;
|
|
3826
|
+
if (!cfg) return null;
|
|
3827
|
+
if (typeof cfg === 'string') return { name: cfg, path: opts.storePath || undefined, clear: !!opts.storeClear };
|
|
3828
|
+
if (typeof cfg === 'object') {
|
|
3829
|
+
return {
|
|
3830
|
+
...cfg,
|
|
3831
|
+
path: cfg.path || opts.storePath || undefined,
|
|
3832
|
+
clear: !!(cfg.clear || opts.storeClear),
|
|
3833
|
+
};
|
|
3834
|
+
}
|
|
3835
|
+
throw new TypeError('runAsync option "store" must be a store name string or a store options object');
|
|
3836
|
+
}
|
|
3837
|
+
|
|
3838
|
+
async function runAsync(input, opts = {}) {
|
|
3839
|
+
const storeConfig = __normalizeStoreOption(opts);
|
|
3840
|
+
const runOpts = __withoutStoreOptions(opts);
|
|
3841
|
+
|
|
3842
|
+
// No store configured: keep ordinary in-memory behavior, but accept async RDF/JS
|
|
3843
|
+
// iterables by normalizing the input before calling the synchronous engine.
|
|
3844
|
+
if (!storeConfig) {
|
|
3845
|
+
const normalizedInput = parseN3SourceList(input, {
|
|
3846
|
+
baseIri: runOpts.baseIri || null,
|
|
3847
|
+
rdf: !!runOpts.rdf,
|
|
3848
|
+
sourceLocations: !!runOpts.proof,
|
|
3849
|
+
}) || (await normalizeReasonerInputAsync(input));
|
|
3850
|
+
return reasonStream(normalizedInput, runOpts);
|
|
3851
|
+
}
|
|
3852
|
+
|
|
3853
|
+
const store = await createFactStore(storeConfig);
|
|
3854
|
+
let closeStore = true;
|
|
3855
|
+
try {
|
|
3856
|
+
const parsed = await __parseRunAsyncInput(input, runOpts);
|
|
3857
|
+
|
|
3858
|
+
// Persist the newly supplied explicit facts first, then include all stored
|
|
3859
|
+
// facts as the starting closure for this run. This lets --store reuse facts
|
|
3860
|
+
// across runs while keeping the current in-memory prover semantics intact.
|
|
3861
|
+
await store.batchAdd(parsed.triples || [], 'explicit');
|
|
3862
|
+
const storedTriples = await collectStore(store);
|
|
3863
|
+
|
|
3864
|
+
const storedKeys = new Set();
|
|
3865
|
+
for (const tr of storedTriples) storedKeys.add(require('./store').tripleToStoreKey(tr));
|
|
3866
|
+
const mergedTriples = storedTriples.slice();
|
|
3867
|
+
for (const tr of parsed.triples || []) {
|
|
3868
|
+
const key = require('./store').tripleToStoreKey(tr);
|
|
3869
|
+
if (!storedKeys.has(key)) {
|
|
3870
|
+
storedKeys.add(key);
|
|
3871
|
+
mergedTriples.push(tr);
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
|
|
3875
|
+
const result = reasonStream(
|
|
3876
|
+
{
|
|
3877
|
+
prefixes: parsed.prefixes,
|
|
3878
|
+
triples: mergedTriples,
|
|
3879
|
+
frules: parsed.frules,
|
|
3880
|
+
brules: parsed.brules,
|
|
3881
|
+
logQueryRules: parsed.logQueryRules,
|
|
3882
|
+
},
|
|
3883
|
+
runOpts,
|
|
3884
|
+
);
|
|
3885
|
+
|
|
3886
|
+
await store.batchAdd((result.derived || []).map((df) => df.fact), 'inferred');
|
|
3887
|
+
result.store = store;
|
|
3888
|
+
closeStore = false;
|
|
3889
|
+
return result;
|
|
3890
|
+
} catch (e) {
|
|
3891
|
+
await store.close();
|
|
3892
|
+
throw e;
|
|
3893
|
+
} finally {
|
|
3894
|
+
// Keep result.store usable for callers. On exceptional paths it is closed
|
|
3895
|
+
// above; on success callers may close it when they are done.
|
|
3896
|
+
if (closeStore) {
|
|
3897
|
+
try { await store.close(); } catch {}
|
|
3898
|
+
}
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
|
|
3786
3902
|
function reasonRdfJs(input, opts = {}) {
|
|
3787
3903
|
const { dataFactory = null, skipUnsupportedRdfJs = false, ...restOpts } = opts || {};
|
|
3788
3904
|
const rdfFactory = getDataFactory(dataFactory);
|
|
@@ -3890,6 +4006,7 @@ function setTracePrefixes(v) {
|
|
|
3890
4006
|
|
|
3891
4007
|
module.exports = {
|
|
3892
4008
|
reasonStream,
|
|
4009
|
+
runAsync,
|
|
3893
4010
|
reasonRdfJs,
|
|
3894
4011
|
collectLogQueryConclusions,
|
|
3895
4012
|
forwardChainAndCollectLogQueryConclusions,
|
|
@@ -3926,4 +4043,7 @@ module.exports = {
|
|
|
3926
4043
|
loadBuiltinModule,
|
|
3927
4044
|
listBuiltinIris,
|
|
3928
4045
|
INFERENCE_FUSE_EXIT_CODE,
|
|
4046
|
+
createFactStore,
|
|
4047
|
+
MemoryFactStore,
|
|
4048
|
+
PersistentFactStore,
|
|
3929
4049
|
};
|
package/lib/entry.js
CHANGED
|
@@ -17,6 +17,7 @@ const { dataFactory } = require('./rdfjs');
|
|
|
17
17
|
module.exports = {
|
|
18
18
|
// public
|
|
19
19
|
reasonStream: engine.reasonStream,
|
|
20
|
+
runAsync: engine.runAsync,
|
|
20
21
|
reasonRdfJs: engine.reasonRdfJs,
|
|
21
22
|
rdfjs: dataFactory,
|
|
22
23
|
main: engine.main,
|
|
@@ -41,6 +42,9 @@ module.exports = {
|
|
|
41
42
|
registerBuiltinModule: engine.registerBuiltinModule,
|
|
42
43
|
loadBuiltinModule: engine.loadBuiltinModule,
|
|
43
44
|
listBuiltinIris: engine.listBuiltinIris,
|
|
45
|
+
createFactStore: engine.createFactStore,
|
|
46
|
+
MemoryFactStore: engine.MemoryFactStore,
|
|
47
|
+
PersistentFactStore: engine.PersistentFactStore,
|
|
44
48
|
getEnforceHttpsEnabled: engine.getEnforceHttpsEnabled,
|
|
45
49
|
setEnforceHttpsEnabled: engine.setEnforceHttpsEnabled,
|
|
46
50
|
getProofCommentsEnabled: engine.getProofCommentsEnabled,
|
package/lib/rdfjs.js
CHANGED
|
@@ -952,6 +952,7 @@ module.exports = {
|
|
|
952
952
|
internalTripleToRdfJsQuads,
|
|
953
953
|
internalTripleToRdfJsQuadInGraph,
|
|
954
954
|
normalizeParsedReasonerInputSync,
|
|
955
|
+
normalizeParsedReasonerInputAsync,
|
|
955
956
|
normalizeReasonerInputSync,
|
|
956
957
|
normalizeReasonerInputAsync,
|
|
957
958
|
hasEyelingObjectInput,
|