eyeling 1.24.31 → 1.25.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 +2 -2
- package/dist/browser/eyeling.browser.js +26 -7
- package/dist/browser/index.mjs +3 -0
- package/examples/deck/rdf-message-flow.md +273 -0
- package/examples/fuse.n3 +1 -1
- package/examples/input/rdf-message-microgrid.trig +39 -72
- package/examples/input/rdf-messages.trig +41 -84
- package/examples/liar.n3 +1 -1
- package/examples/output/rdf-message-microgrid.md +4 -6
- package/examples/output/rdf-messages.md +3 -5
- package/examples/rdf-message-microgrid.n3 +54 -68
- package/examples/rdf-messages.n3 +63 -76
- package/eyeling.js +26 -7
- package/index.d.ts +3 -0
- package/lib/builtins.js +18 -5
- package/lib/engine.js +7 -2
- package/lib/entry.js +1 -0
- package/package.json +1 -1
- package/test/api.test.js +34 -5
- package/test/package.test.js +2 -2
- package/tools/bundle.js +3 -0
package/eyeling.js
CHANGED
|
@@ -1207,25 +1207,36 @@ function parseXsdDateTerm(t) {
|
|
|
1207
1207
|
return d;
|
|
1208
1208
|
}
|
|
1209
1209
|
|
|
1210
|
+
function isXsdDateTimeDatatype(dt) {
|
|
1211
|
+
return dt === XSD_NS + 'dateTime' || dt === XSD_NS + 'dateTimeStamp';
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1210
1214
|
function parseXsdDatetimeTerm(t) {
|
|
1211
1215
|
if (!(t instanceof Literal)) return null;
|
|
1212
1216
|
const [lex, dt] = literalParts(t.value);
|
|
1213
|
-
if (dt
|
|
1217
|
+
if (!isXsdDateTimeDatatype(dt)) return null;
|
|
1214
1218
|
const val = stripQuotes(lex);
|
|
1219
|
+
|
|
1220
|
+
// xsd:dateTimeStamp is a subtype of xsd:dateTime with a required timezone.
|
|
1221
|
+
// Keep xsd:dateTime's existing permissive behaviour, but reject stamp
|
|
1222
|
+
// lexicals that do not actually carry the required timezone.
|
|
1223
|
+
if (dt === XSD_NS + 'dateTimeStamp' && !/(Z|[+-]\d{2}:\d{2})$/.test(val)) return null;
|
|
1224
|
+
|
|
1215
1225
|
const d = new Date(val);
|
|
1216
1226
|
if (Number.isNaN(d.getTime())) return null;
|
|
1217
1227
|
return d; // Date in local/UTC, we only use timestamp
|
|
1218
1228
|
}
|
|
1219
1229
|
|
|
1220
1230
|
function parseXsdDateTimeLexParts(t) {
|
|
1221
|
-
// Parse *lexical* components of an xsd:dateTime literal without timezone normalization.
|
|
1231
|
+
// Parse *lexical* components of an xsd:dateTime/dateTimeStamp literal without timezone normalization.
|
|
1222
1232
|
// Returns { yearStr, month, day, hour, minute, second, tz } or null.
|
|
1223
1233
|
if (!(t instanceof Literal)) return null;
|
|
1224
1234
|
const [lex, dt] = literalParts(t.value);
|
|
1225
|
-
if (dt
|
|
1235
|
+
if (!isXsdDateTimeDatatype(dt)) return null;
|
|
1226
1236
|
const val = stripQuotes(lex);
|
|
1227
1237
|
|
|
1228
1238
|
// xsd:dateTime lexical: YYYY-MM-DDThh:mm:ss(.s+)?(Z|(+|-)hh:mm)?
|
|
1239
|
+
// xsd:dateTimeStamp has the same lexical form, but with the timezone required.
|
|
1229
1240
|
const m = /^(-?\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(Z|[+-]\d{2}:\d{2})?$/.exec(val);
|
|
1230
1241
|
if (!m) return null;
|
|
1231
1242
|
|
|
@@ -1236,6 +1247,7 @@ function parseXsdDateTimeLexParts(t) {
|
|
|
1236
1247
|
const minute = parseInt(m[5], 10);
|
|
1237
1248
|
const second = parseInt(m[6], 10);
|
|
1238
1249
|
const tz = m[7] || null;
|
|
1250
|
+
if (dt === XSD_NS + 'dateTimeStamp' && !tz) return null;
|
|
1239
1251
|
|
|
1240
1252
|
if (!(month >= 1 && month <= 12)) return null;
|
|
1241
1253
|
if (!(day >= 1 && day <= 31)) return null;
|
|
@@ -1302,7 +1314,8 @@ function parseIso8601DurationToSeconds(s) {
|
|
|
1302
1314
|
}
|
|
1303
1315
|
|
|
1304
1316
|
function parseNumericForCompareTerm(t) {
|
|
1305
|
-
// Strict: only accept xsd numeric literals, xsd:duration, xsd:date,
|
|
1317
|
+
// Strict: only accept xsd numeric literals, xsd:duration, xsd:date,
|
|
1318
|
+
// xsd:dateTime, and xsd:dateTimeStamp.
|
|
1306
1319
|
// (or untyped numeric tokens).
|
|
1307
1320
|
const bi = parseIntLiteral(t);
|
|
1308
1321
|
if (bi !== null) return { kind: 'bigint', value: bi };
|
|
@@ -1369,7 +1382,7 @@ function parseNumOrDuration(t) {
|
|
|
1369
1382
|
}
|
|
1370
1383
|
}
|
|
1371
1384
|
|
|
1372
|
-
// xsd:date / xsd:dateTime
|
|
1385
|
+
// xsd:date / xsd:dateTime / xsd:dateTimeStamp
|
|
1373
1386
|
const dtval = parseDatetimeLike(t);
|
|
1374
1387
|
if (dtval !== null) {
|
|
1375
1388
|
return dtval.getTime() / 1000.0;
|
|
@@ -5504,6 +5517,10 @@ const {
|
|
|
5504
5517
|
copyQuotedGraphMetadata,
|
|
5505
5518
|
} = require('./prelude');
|
|
5506
5519
|
|
|
5520
|
+
// Inference fuses use sysexits.h EX_DATAERR (65): input/rules made a
|
|
5521
|
+
// forbidden condition provable, rather than a generic usage/runtime error.
|
|
5522
|
+
const INFERENCE_FUSE_EXIT_CODE = 65;
|
|
5523
|
+
|
|
5507
5524
|
// In N3/Turtle, rdf:nil is the canonical IRI for the empty RDF list.
|
|
5508
5525
|
// Eyeling represents list literals with ListTerm; ensure rdf:nil unifies with ().
|
|
5509
5526
|
const RDF_NIL_IRI = RDF_NS + 'nil';
|
|
@@ -8432,7 +8449,7 @@ function forwardChain(facts, forwardRules, backRules, onDerived /* optional */,
|
|
|
8432
8449
|
// Allow dynamic fuses: ... => ?X. where ?X becomes false
|
|
8433
8450
|
if (dynTerm instanceof Literal && dynTerm.value === 'false') {
|
|
8434
8451
|
__printTriggeredFuse(r, opts && opts.prefixes, s, 'Dynamic head resolved to false.');
|
|
8435
|
-
__exitReasoning(
|
|
8452
|
+
__exitReasoning(INFERENCE_FUSE_EXIT_CODE, 'Inference fuse triggered.');
|
|
8436
8453
|
}
|
|
8437
8454
|
|
|
8438
8455
|
const dynTriples = __graphTriplesOrTrue(dynTerm);
|
|
@@ -8593,7 +8610,7 @@ function forwardChain(facts, forwardRules, backRules, onDerived /* optional */,
|
|
|
8593
8610
|
// Inference fuse
|
|
8594
8611
|
if (r.isFuse && sols.length) {
|
|
8595
8612
|
__printTriggeredFuse(r, opts && opts.prefixes, sols[0]);
|
|
8596
|
-
__exitReasoning(
|
|
8613
|
+
__exitReasoning(INFERENCE_FUSE_EXIT_CODE, 'Inference fuse triggered.');
|
|
8597
8614
|
}
|
|
8598
8615
|
|
|
8599
8616
|
for (const s of sols) {
|
|
@@ -9130,6 +9147,7 @@ module.exports = {
|
|
|
9130
9147
|
registerBuiltinModule,
|
|
9131
9148
|
loadBuiltinModule,
|
|
9132
9149
|
listBuiltinIris,
|
|
9150
|
+
INFERENCE_FUSE_EXIT_CODE,
|
|
9133
9151
|
};
|
|
9134
9152
|
|
|
9135
9153
|
};
|
|
@@ -9157,6 +9175,7 @@ module.exports = {
|
|
|
9157
9175
|
rdfjs: dataFactory,
|
|
9158
9176
|
main: engine.main,
|
|
9159
9177
|
version: engine.version,
|
|
9178
|
+
INFERENCE_FUSE_EXIT_CODE: engine.INFERENCE_FUSE_EXIT_CODE,
|
|
9160
9179
|
|
|
9161
9180
|
// internals for playground.html
|
|
9162
9181
|
lex: engine.lex,
|
package/index.d.ts
CHANGED
|
@@ -209,6 +209,7 @@ declare module 'eyeling' {
|
|
|
209
209
|
opts?: Omit<ReasonStreamOptions, 'rdfjs' | 'onDerived'>,
|
|
210
210
|
): AsyncIterable<RdfJsQuad>;
|
|
211
211
|
|
|
212
|
+
export const INFERENCE_FUSE_EXIT_CODE: 65;
|
|
212
213
|
export const rdfjs: RdfJsDataFactory;
|
|
213
214
|
export function registerBuiltin(iri: string, handler: BuiltinHandler): BuiltinHandler;
|
|
214
215
|
export function unregisterBuiltin(iri: string): boolean;
|
|
@@ -237,6 +238,7 @@ declare module 'eyeling/browser' {
|
|
|
237
238
|
opts?: Omit<ReasonStreamOptions, 'rdfjs' | 'onDerived'>,
|
|
238
239
|
): AsyncIterable<RdfJsQuad>;
|
|
239
240
|
|
|
241
|
+
export const INFERENCE_FUSE_EXIT_CODE: 65;
|
|
240
242
|
export const rdfjs: RdfJsDataFactory;
|
|
241
243
|
export function registerBuiltin(iri: string, handler: BuiltinHandler): BuiltinHandler;
|
|
242
244
|
export function unregisterBuiltin(iri: string): boolean;
|
|
@@ -247,6 +249,7 @@ declare module 'eyeling/browser' {
|
|
|
247
249
|
readonly version: string;
|
|
248
250
|
reasonStream: typeof reasonStream;
|
|
249
251
|
reasonRdfJs: typeof reasonRdfJs;
|
|
252
|
+
readonly INFERENCE_FUSE_EXIT_CODE: typeof INFERENCE_FUSE_EXIT_CODE;
|
|
250
253
|
rdfjs: typeof rdfjs;
|
|
251
254
|
registerBuiltin: typeof registerBuiltin;
|
|
252
255
|
unregisterBuiltin: typeof unregisterBuiltin;
|
package/lib/builtins.js
CHANGED
|
@@ -1196,25 +1196,36 @@ function parseXsdDateTerm(t) {
|
|
|
1196
1196
|
return d;
|
|
1197
1197
|
}
|
|
1198
1198
|
|
|
1199
|
+
function isXsdDateTimeDatatype(dt) {
|
|
1200
|
+
return dt === XSD_NS + 'dateTime' || dt === XSD_NS + 'dateTimeStamp';
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1199
1203
|
function parseXsdDatetimeTerm(t) {
|
|
1200
1204
|
if (!(t instanceof Literal)) return null;
|
|
1201
1205
|
const [lex, dt] = literalParts(t.value);
|
|
1202
|
-
if (dt
|
|
1206
|
+
if (!isXsdDateTimeDatatype(dt)) return null;
|
|
1203
1207
|
const val = stripQuotes(lex);
|
|
1208
|
+
|
|
1209
|
+
// xsd:dateTimeStamp is a subtype of xsd:dateTime with a required timezone.
|
|
1210
|
+
// Keep xsd:dateTime's existing permissive behaviour, but reject stamp
|
|
1211
|
+
// lexicals that do not actually carry the required timezone.
|
|
1212
|
+
if (dt === XSD_NS + 'dateTimeStamp' && !/(Z|[+-]\d{2}:\d{2})$/.test(val)) return null;
|
|
1213
|
+
|
|
1204
1214
|
const d = new Date(val);
|
|
1205
1215
|
if (Number.isNaN(d.getTime())) return null;
|
|
1206
1216
|
return d; // Date in local/UTC, we only use timestamp
|
|
1207
1217
|
}
|
|
1208
1218
|
|
|
1209
1219
|
function parseXsdDateTimeLexParts(t) {
|
|
1210
|
-
// Parse *lexical* components of an xsd:dateTime literal without timezone normalization.
|
|
1220
|
+
// Parse *lexical* components of an xsd:dateTime/dateTimeStamp literal without timezone normalization.
|
|
1211
1221
|
// Returns { yearStr, month, day, hour, minute, second, tz } or null.
|
|
1212
1222
|
if (!(t instanceof Literal)) return null;
|
|
1213
1223
|
const [lex, dt] = literalParts(t.value);
|
|
1214
|
-
if (dt
|
|
1224
|
+
if (!isXsdDateTimeDatatype(dt)) return null;
|
|
1215
1225
|
const val = stripQuotes(lex);
|
|
1216
1226
|
|
|
1217
1227
|
// xsd:dateTime lexical: YYYY-MM-DDThh:mm:ss(.s+)?(Z|(+|-)hh:mm)?
|
|
1228
|
+
// xsd:dateTimeStamp has the same lexical form, but with the timezone required.
|
|
1218
1229
|
const m = /^(-?\d{4,})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(Z|[+-]\d{2}:\d{2})?$/.exec(val);
|
|
1219
1230
|
if (!m) return null;
|
|
1220
1231
|
|
|
@@ -1225,6 +1236,7 @@ function parseXsdDateTimeLexParts(t) {
|
|
|
1225
1236
|
const minute = parseInt(m[5], 10);
|
|
1226
1237
|
const second = parseInt(m[6], 10);
|
|
1227
1238
|
const tz = m[7] || null;
|
|
1239
|
+
if (dt === XSD_NS + 'dateTimeStamp' && !tz) return null;
|
|
1228
1240
|
|
|
1229
1241
|
if (!(month >= 1 && month <= 12)) return null;
|
|
1230
1242
|
if (!(day >= 1 && day <= 31)) return null;
|
|
@@ -1291,7 +1303,8 @@ function parseIso8601DurationToSeconds(s) {
|
|
|
1291
1303
|
}
|
|
1292
1304
|
|
|
1293
1305
|
function parseNumericForCompareTerm(t) {
|
|
1294
|
-
// Strict: only accept xsd numeric literals, xsd:duration, xsd:date,
|
|
1306
|
+
// Strict: only accept xsd numeric literals, xsd:duration, xsd:date,
|
|
1307
|
+
// xsd:dateTime, and xsd:dateTimeStamp.
|
|
1295
1308
|
// (or untyped numeric tokens).
|
|
1296
1309
|
const bi = parseIntLiteral(t);
|
|
1297
1310
|
if (bi !== null) return { kind: 'bigint', value: bi };
|
|
@@ -1358,7 +1371,7 @@ function parseNumOrDuration(t) {
|
|
|
1358
1371
|
}
|
|
1359
1372
|
}
|
|
1360
1373
|
|
|
1361
|
-
// xsd:date / xsd:dateTime
|
|
1374
|
+
// xsd:date / xsd:dateTime / xsd:dateTimeStamp
|
|
1362
1375
|
const dtval = parseDatetimeLike(t);
|
|
1363
1376
|
if (dtval !== null) {
|
|
1364
1377
|
return dtval.getTime() / 1000.0;
|
package/lib/engine.js
CHANGED
|
@@ -30,6 +30,10 @@ const {
|
|
|
30
30
|
copyQuotedGraphMetadata,
|
|
31
31
|
} = require('./prelude');
|
|
32
32
|
|
|
33
|
+
// Inference fuses use sysexits.h EX_DATAERR (65): input/rules made a
|
|
34
|
+
// forbidden condition provable, rather than a generic usage/runtime error.
|
|
35
|
+
const INFERENCE_FUSE_EXIT_CODE = 65;
|
|
36
|
+
|
|
33
37
|
// In N3/Turtle, rdf:nil is the canonical IRI for the empty RDF list.
|
|
34
38
|
// Eyeling represents list literals with ListTerm; ensure rdf:nil unifies with ().
|
|
35
39
|
const RDF_NIL_IRI = RDF_NS + 'nil';
|
|
@@ -2958,7 +2962,7 @@ function forwardChain(facts, forwardRules, backRules, onDerived /* optional */,
|
|
|
2958
2962
|
// Allow dynamic fuses: ... => ?X. where ?X becomes false
|
|
2959
2963
|
if (dynTerm instanceof Literal && dynTerm.value === 'false') {
|
|
2960
2964
|
__printTriggeredFuse(r, opts && opts.prefixes, s, 'Dynamic head resolved to false.');
|
|
2961
|
-
__exitReasoning(
|
|
2965
|
+
__exitReasoning(INFERENCE_FUSE_EXIT_CODE, 'Inference fuse triggered.');
|
|
2962
2966
|
}
|
|
2963
2967
|
|
|
2964
2968
|
const dynTriples = __graphTriplesOrTrue(dynTerm);
|
|
@@ -3119,7 +3123,7 @@ function forwardChain(facts, forwardRules, backRules, onDerived /* optional */,
|
|
|
3119
3123
|
// Inference fuse
|
|
3120
3124
|
if (r.isFuse && sols.length) {
|
|
3121
3125
|
__printTriggeredFuse(r, opts && opts.prefixes, sols[0]);
|
|
3122
|
-
__exitReasoning(
|
|
3126
|
+
__exitReasoning(INFERENCE_FUSE_EXIT_CODE, 'Inference fuse triggered.');
|
|
3123
3127
|
}
|
|
3124
3128
|
|
|
3125
3129
|
for (const s of sols) {
|
|
@@ -3656,4 +3660,5 @@ module.exports = {
|
|
|
3656
3660
|
registerBuiltinModule,
|
|
3657
3661
|
loadBuiltinModule,
|
|
3658
3662
|
listBuiltinIris,
|
|
3663
|
+
INFERENCE_FUSE_EXIT_CODE,
|
|
3659
3664
|
};
|
package/lib/entry.js
CHANGED
package/package.json
CHANGED
package/test/api.test.js
CHANGED
|
@@ -323,6 +323,35 @@ const cases = [
|
|
|
323
323
|
assert.match(out, /\\"2023-04-01T18:06:04Z\\"\^\^xsd:dateTime \./);
|
|
324
324
|
},
|
|
325
325
|
},
|
|
326
|
+
{
|
|
327
|
+
name: '00d math comparison accepts xsd:dateTimeStamp with xsd:dateTime',
|
|
328
|
+
opt: { proofComments: false },
|
|
329
|
+
input: `
|
|
330
|
+
@prefix : <http://example.org/> .
|
|
331
|
+
@prefix math: <http://www.w3.org/2000/10/swap/math#> .
|
|
332
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
333
|
+
|
|
334
|
+
{
|
|
335
|
+
"2026-05-30T00:00:00Z"^^xsd:dateTimeStamp math:notGreaterThan "2027-02-12T00:00:00Z"^^xsd:dateTime .
|
|
336
|
+
}
|
|
337
|
+
=>
|
|
338
|
+
{
|
|
339
|
+
:mixedDateTimeStampCompare :is true .
|
|
340
|
+
}.
|
|
341
|
+
|
|
342
|
+
{
|
|
343
|
+
"2026-05-30T00:00:00Z"^^xsd:dateTimeStamp math:notGreaterThan "2026-05-30T00:00:00Z"^^xsd:dateTimeStamp .
|
|
344
|
+
}
|
|
345
|
+
=>
|
|
346
|
+
{
|
|
347
|
+
:sameDateTimeStampCompare :is true .
|
|
348
|
+
}.
|
|
349
|
+
`,
|
|
350
|
+
expect: [
|
|
351
|
+
/:mixedDateTimeStampCompare\s+:is\s+true\s*\./,
|
|
352
|
+
/:sameDateTimeStampCompare\s+:is\s+true\s*\./,
|
|
353
|
+
],
|
|
354
|
+
},
|
|
326
355
|
{
|
|
327
356
|
name: '01 forward rule: p -> q',
|
|
328
357
|
opt: { proofComments: false },
|
|
@@ -428,13 +457,13 @@ ${U('s')} ${U('p')} ${U('o')}.
|
|
|
428
457
|
notExpect: [/^#/m],
|
|
429
458
|
},
|
|
430
459
|
{
|
|
431
|
-
name: '11 negative entailment: rule derives false (expect exit
|
|
460
|
+
name: '11 negative entailment: rule derives false (expect exit 65 => throws)',
|
|
432
461
|
opt: { proofComments: false },
|
|
433
462
|
input: `
|
|
434
463
|
{ ${U('a')} ${U('p')} ${U('b')}. } => false.
|
|
435
464
|
${U('a')} ${U('p')} ${U('b')}.
|
|
436
465
|
`,
|
|
437
|
-
expectErrorCode:
|
|
466
|
+
expectErrorCode: 65,
|
|
438
467
|
},
|
|
439
468
|
{
|
|
440
469
|
name: '12 invalid syntax should throw (non-zero exit)',
|
|
@@ -958,10 +987,10 @@ ${transitiveClosureN3('sub')}
|
|
|
958
987
|
],
|
|
959
988
|
},
|
|
960
989
|
{
|
|
961
|
-
name: '25 heavier negative entailment: batch + forbidden => false (expect exit
|
|
990
|
+
name: '25 heavier negative entailment: batch + forbidden => false (expect exit 65)',
|
|
962
991
|
opt: { proofComments: false, maxBuffer: 200 * 1024 * 1024 },
|
|
963
992
|
input: negativeEntailmentBatchN3(200),
|
|
964
|
-
expectErrorCode:
|
|
993
|
+
expectErrorCode: 65,
|
|
965
994
|
},
|
|
966
995
|
{
|
|
967
996
|
name: '26 sanity: no rules => no newly derived facts',
|
|
@@ -1079,7 +1108,7 @@ ${U('a')} ${U('p')} ${U('b')}.
|
|
|
1079
1108
|
{ ${U('a')} ${U('p')} ${U('b')}. } => { ${U('a')} ${U('q')} ${U('b')}. }.
|
|
1080
1109
|
{ ${U('a')} ${U('q')} ${U('b')}. } => false.
|
|
1081
1110
|
`,
|
|
1082
|
-
expectErrorCode:
|
|
1111
|
+
expectErrorCode: 65,
|
|
1083
1112
|
},
|
|
1084
1113
|
|
|
1085
1114
|
{
|
package/test/package.test.js
CHANGED
|
@@ -79,12 +79,12 @@ function normalizeMarkdownForCompare(text) {
|
|
|
79
79
|
|
|
80
80
|
// Expectation logic (shared with test/examples.test.js):
|
|
81
81
|
// 1) If file contains: # expect-exit: N -> use N
|
|
82
|
-
// 2) Else, if it contains "=> false" -> expect exit
|
|
82
|
+
// 2) Else, if it contains "=> false" -> expect exit 65
|
|
83
83
|
// 3) Else -> expect exit 0
|
|
84
84
|
function expectedExitCode(n3Text) {
|
|
85
85
|
const m = n3Text.match(/^[ \t]*#[: ]*expect-exit:[ \t]*([0-9]+)\b/m);
|
|
86
86
|
if (m) return parseInt(m[1], 10);
|
|
87
|
-
if (/=>\s*false\b/.test(n3Text)) return
|
|
87
|
+
if (/=>\s*false\b/.test(n3Text)) return 65;
|
|
88
88
|
return 0;
|
|
89
89
|
}
|
|
90
90
|
|
package/tools/bundle.js
CHANGED
|
@@ -229,6 +229,8 @@ function getBrowserApi() {
|
|
|
229
229
|
return api;
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
+
export const INFERENCE_FUSE_EXIT_CODE = 65;
|
|
233
|
+
|
|
232
234
|
export function reasonStream(input, opts) {
|
|
233
235
|
return getBrowserApi().reasonStream(input, opts);
|
|
234
236
|
}
|
|
@@ -283,6 +285,7 @@ const eyeling = {
|
|
|
283
285
|
get version() {
|
|
284
286
|
return getBrowserApi().version;
|
|
285
287
|
},
|
|
288
|
+
INFERENCE_FUSE_EXIT_CODE,
|
|
286
289
|
reasonStream,
|
|
287
290
|
reasonRdfJs,
|
|
288
291
|
rdfjs,
|