@factoidal/core 0.7.1 → 0.10.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/CHANGELOG.md +503 -1
- package/NOTICE +2 -21
- package/README.md +117 -993
- package/api.d.ts +53 -0
- package/api.js +5 -0
- package/api.mjs +56 -0
- package/bin/engine.mjs +38 -19
- package/bin/factoidal.mjs +512 -66
- package/bin/pack.mjs +37 -0
- package/bin/serve-worker.mjs +32 -0
- package/bin/serve.mjs +423 -0
- package/bin/store-worker-host.mjs +1 -1
- package/bin/store.mjs +1 -1
- package/browser.d.ts +110 -507
- package/browser.js +151 -2257
- package/docs/fuseki-replacement.md +108 -0
- package/fn.d.ts +24 -95
- package/fn.js +104 -150
- package/index.d.ts +598 -259
- package/index.js +4 -234
- package/index.mjs +176 -84
- package/l4-assets/l4factoidal.js +47 -7
- package/l4-assets/l4factoidal.mjs +1 -1
- package/l4-assets/l4factoidal.wasm +0 -0
- package/l4-assets/version.json +11 -7
- package/lib/api.mjs +2300 -0
- package/lib/browser-engine.mjs +69 -0
- package/lib/dataset.mjs +377 -0
- package/lib/delta-log-hosts.mjs +191 -0
- package/lib/lean-entry.mjs +204 -0
- package/lib/pure.mjs +98 -0
- package/lib/store.mjs +115 -0
- package/lib/version.mjs +5 -0
- package/lws/README.md +97 -0
- package/lws/server.mjs +331 -0
- package/package.json +59 -61
- package/rdfjs.js +5 -536
- package/rdfjs.mjs +594 -0
- package/sample-store.d.ts +8 -16
- package/sample-store.mjs +39 -29
- package/solid/client/README.md +100 -0
- package/solid/client/index.mjs +277 -0
- package/solid/server/README.md +96 -0
- package/solid/server/index.mjs +317 -0
- package/store-host/deno.mjs +8 -0
- package/store-host/index.mjs +12 -0
- package/store-host/node.mjs +8 -0
- package/xmpp/README.md +107 -0
- package/xmpp/index.mjs +229 -0
- package/browser-wasm.js +0 -872
- package/factoidal-npm-entry.js +0 -15477
- package/factoidal-npm-entry.wasm.assets/code-5a7fc68f2ab1323718b8.wasm +0 -0
- package/factoidal-npm-entry.wasm.js +0 -455
- package/factoidal.js +0 -13118
- package/factoidal.wasm.assets/code-bbe6099bfb5b10c4c3ab.wasm +0 -0
- package/factoidal.wasm.js +0 -457
- package/hacl-init.js +0 -92
- package/hacl-wasm/FStar.wasm +0 -0
- package/hacl-wasm/Hacl_Bignum.wasm +0 -0
- package/hacl-wasm/Hacl_Bignum25519_51.wasm +0 -0
- package/hacl-wasm/Hacl_Bignum_Base.wasm +0 -0
- package/hacl-wasm/Hacl_Curve25519_51.wasm +0 -0
- package/hacl-wasm/Hacl_Ed25519.wasm +0 -0
- package/hacl-wasm/Hacl_Ed25519_PrecompTable.wasm +0 -0
- package/hacl-wasm/Hacl_Hash_Base.wasm +0 -0
- package/hacl-wasm/Hacl_Hash_SHA2.wasm +0 -0
- package/hacl-wasm/Hacl_IntTypes_Intrinsics.wasm +0 -0
- package/hacl-wasm/LowStar_Endianness.wasm +0 -0
- package/hacl-wasm/WasmSupport.wasm +0 -0
- package/hacl-wasm/api.js +0 -775
- package/hacl-wasm/api.json +0 -3787
- package/hacl-wasm/layouts.json +0 -1
- package/hacl-wasm/loader.js +0 -568
- package/hacl-wasm/shell.js +0 -12
- package/l4-core.d.ts +0 -159
- package/l4-core.js +0 -188
- package/l4.d.ts +0 -50
- package/l4.js +0 -104
- package/lib/api.js +0 -2300
- package/lib/engine-js.js +0 -165
- package/lib/engine-wasm.js +0 -300
- package/sample-store/CURRENT +0 -1
- package/sample-store/gen-1/manifest.sbm2 +0 -0
- package/sample-store/gen-1/manifest.tsv +0 -14
- package/sample-store/gen-1/predicate-0.ibk3 +0 -0
- package/sample-store/gen-1/predicate-0.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-0.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-0.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-0.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-0.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-0.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-0.ibk3.tli1.merkle +0 -0
- package/sample-store/gen-1/predicate-1.ibk3 +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.merkle +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.oli2.merkle +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-1.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-1.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-10.ibk3 +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-10.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.oli2.merkle +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-10.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-10.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-11.ibk3 +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.merkle +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-11.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-11.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-11.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-12.ibk3 +0 -0
- package/sample-store/gen-1/predicate-12.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-12.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-12.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-12.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-12.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-12.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-12.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-2.ibk3 +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-2.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-2.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.sri2.merkle +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-2.ibk3.tli1.merkle +0 -0
- package/sample-store/gen-1/predicate-3.ibk3 +0 -0
- package/sample-store/gen-1/predicate-3.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-3.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-3.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-3.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-3.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-3.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-3.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-4.ibk3 +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.merkle +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-4.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-4.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-4.ibk3.tli1.merkle +0 -2
- package/sample-store/gen-1/predicate-5.ibk3 +0 -0
- package/sample-store/gen-1/predicate-5.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-5.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-5.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-5.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-5.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-5.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-5.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-6.ibk3 +0 -0
- package/sample-store/gen-1/predicate-6.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-6.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-6.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-6.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-6.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-6.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-6.ibk3.tli1.merkle +0 -0
- package/sample-store/gen-1/predicate-7.ibk3 +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.merkle +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.oli2.merkle +0 -2
- package/sample-store/gen-1/predicate-7.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-7.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-7.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-8.ibk3 +0 -0
- package/sample-store/gen-1/predicate-8.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-8.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-8.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-8.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-8.ibk3.sri2.merkle +0 -1
- package/sample-store/gen-1/predicate-8.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-8.ibk3.tli1.merkle +0 -1
- package/sample-store/gen-1/predicate-9.ibk3 +0 -0
- package/sample-store/gen-1/predicate-9.ibk3.merkle +0 -1
- package/sample-store/gen-1/predicate-9.ibk3.oli2 +0 -0
- package/sample-store/gen-1/predicate-9.ibk3.oli2.merkle +0 -1
- package/sample-store/gen-1/predicate-9.ibk3.sri2 +0 -0
- package/sample-store/gen-1/predicate-9.ibk3.sri2.merkle +0 -3
- package/sample-store/gen-1/predicate-9.ibk3.tli1 +0 -0
- package/sample-store/gen-1/predicate-9.ibk3.tli1.merkle +0 -2
- package/select.d.ts +0 -116
- package/select.js +0 -492
- package/version.json +0 -102
- package/wasm.d.ts +0 -130
- package/wasm.js +0 -158
package/fn.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// factoidal/fn — a strictly functional dataset API.
|
|
2
2
|
//
|
|
3
|
-
// Every
|
|
4
|
-
// has no mutation to expose); RDF/JS DatasetCore's add/delete is
|
|
3
|
+
// Every engine operation is a value-to-value function (the Lean
|
|
4
|
+
// library has no mutation to expose); RDF/JS DatasetCore's add/delete is
|
|
5
5
|
// wrapper-side skeuomorphism on top of that. This module makes the JS
|
|
6
6
|
// contract match the verified one: FnDataset is a frozen snapshot, all
|
|
7
7
|
// operations are free functions that return new values, and content
|
|
@@ -25,7 +25,7 @@ const crypto = require('node:crypto');
|
|
|
25
25
|
|
|
26
26
|
const engineApi = require('./index.js');
|
|
27
27
|
const {
|
|
28
|
-
|
|
28
|
+
DatasetCore,
|
|
29
29
|
dataFactory,
|
|
30
30
|
quadToNQuads,
|
|
31
31
|
quadsToNQuads,
|
|
@@ -92,10 +92,34 @@ function arrayBackend(quads) {
|
|
|
92
92
|
kind: 'array',
|
|
93
93
|
size: quads.length,
|
|
94
94
|
quads: () => quads,
|
|
95
|
+
engine: null,
|
|
95
96
|
precomputedHash: null,
|
|
96
97
|
};
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
// The engine backend (0.10.0, issue 882 of danbri/factoidal): the quads are
|
|
101
|
+
// an engine Dataset (lib/dataset.mjs) that this module never changes. Every
|
|
102
|
+
// engine operation takes that Dataset itself, so no N-Quads text crosses
|
|
103
|
+
// between steps. The JS quad array is read once, on demand.
|
|
104
|
+
function engineBackend(eds) {
|
|
105
|
+
let quads = null;
|
|
106
|
+
return {
|
|
107
|
+
kind: 'engine',
|
|
108
|
+
size: eds.size,
|
|
109
|
+
quads: () => (quads ||= Object.freeze(eds.toArray())),
|
|
110
|
+
engine: eds,
|
|
111
|
+
precomputedHash: null,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// An FnDataset over an engine Dataset this module made and never shares.
|
|
116
|
+
function wrapEngine(eds) {
|
|
117
|
+
return new FnDataset(engineBackend(eds));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ds (array-backed FnDataset) -> engine Dataset, opened once from its quads.
|
|
121
|
+
const ENGINE_CACHE = new WeakMap();
|
|
122
|
+
|
|
99
123
|
// Build a de-duplicated FnDataset from any iterable of RDF/JS quads.
|
|
100
124
|
// Every public constructor path (fromDataset, union, difference,
|
|
101
125
|
// filter, mapQuads, query's CONSTRUCT wrapping, builder().finish())
|
|
@@ -147,14 +171,15 @@ class FnDataset {
|
|
|
147
171
|
toNQuads() {
|
|
148
172
|
let cached = NQUADS_CACHE.get(this);
|
|
149
173
|
if (cached === undefined) {
|
|
150
|
-
cached = quadsToNQuads(this.toArray());
|
|
174
|
+
cached = this._backend.engine ? this._backend.engine.toNQuads() : quadsToNQuads(this.toArray());
|
|
151
175
|
NQUADS_CACHE.set(this, cached);
|
|
152
176
|
}
|
|
153
177
|
return cached;
|
|
154
178
|
}
|
|
155
179
|
|
|
156
|
-
/** Read-only quad-pattern match (RDF/JS DatasetCore shape)
|
|
180
|
+
/** Read-only quad-pattern match (RDF/JS DatasetCore shape); the engine's indexes for an engine-backed dataset. */
|
|
157
181
|
match(subject, predicate, object, graph) {
|
|
182
|
+
if (this._backend.engine) return wrapEngine(this._backend.engine.match(subject, predicate, object, graph));
|
|
158
183
|
return makeFnDataset(this.toArray().filter((q) =>
|
|
159
184
|
(!subject || subject.equals(q.subject)) &&
|
|
160
185
|
(!predicate || predicate.equals(q.predicate)) &&
|
|
@@ -170,18 +195,31 @@ const EMPTY = new FnDataset(arrayBackend(Object.freeze([])));
|
|
|
170
195
|
// Interop with the mutable RDF/JS layer.
|
|
171
196
|
// ---------------------------------------------------------------------
|
|
172
197
|
|
|
173
|
-
/** Snapshot a (
|
|
198
|
+
/** Snapshot a Dataset (the engine's, or an RDF/JS DatasetCore) into an FnDataset. */
|
|
174
199
|
function fromDataset(dataset) {
|
|
175
|
-
if (
|
|
176
|
-
|
|
200
|
+
if (dataset instanceof engineApi.Dataset) return wrapEngine(dataset.clone());
|
|
201
|
+
if (!(dataset instanceof DatasetCore)) {
|
|
202
|
+
throw new TypeError('fromDataset: expected a Dataset or an RDF/JS DatasetCore');
|
|
177
203
|
}
|
|
178
204
|
return makeFnDataset(dataset);
|
|
179
205
|
}
|
|
180
206
|
|
|
181
|
-
|
|
207
|
+
// The engine Dataset of an FnDataset: its own, or (for one built from JS
|
|
208
|
+
// quads) one opened from its quads once and kept.
|
|
209
|
+
async function engineOf(ds) {
|
|
210
|
+
if (ds._backend.engine) return ds._backend.engine;
|
|
211
|
+
let eds = ENGINE_CACHE.get(ds);
|
|
212
|
+
if (!eds) {
|
|
213
|
+
eds = await engineApi.openDataset({ text: quadsToNQuads(ds.toArray()), format: 'nquads' });
|
|
214
|
+
ENGINE_CACHE.set(ds, eds);
|
|
215
|
+
}
|
|
216
|
+
return eds;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Materialize an FnDataset into a fresh, independently-mutable RDF/JS DatasetCore. */
|
|
182
220
|
function toDataset(ds) {
|
|
183
221
|
assertFnDataset(ds, 'toDataset');
|
|
184
|
-
return new
|
|
222
|
+
return new DatasetCore(ds.toArray());
|
|
185
223
|
}
|
|
186
224
|
|
|
187
225
|
// ---------------------------------------------------------------------
|
|
@@ -247,7 +285,7 @@ async function fromChunks(chunks) {
|
|
|
247
285
|
|
|
248
286
|
/** Parse one RDF document into an FnDataset. Mirrors index.js's parse(). */
|
|
249
287
|
async function parse(text, options) {
|
|
250
|
-
return
|
|
288
|
+
return wrapEngine(await engineApi.parse(text, options));
|
|
251
289
|
}
|
|
252
290
|
|
|
253
291
|
/** Set union, first-seen order (a's quads, then b's not already present). */
|
|
@@ -291,31 +329,22 @@ function mapQuads(ds, f) {
|
|
|
291
329
|
|
|
292
330
|
/**
|
|
293
331
|
* Run a SPARQL 1.1 query. SELECT -> Bindings[]; ASK -> boolean;
|
|
294
|
-
* CONSTRUCT -> FnDataset. Delegates entirely to index.js's
|
|
295
|
-
*
|
|
296
|
-
* absence throws the existing "pending npm-entry build" Error).
|
|
332
|
+
* CONSTRUCT and DESCRIBE -> FnDataset. Delegates entirely to index.js's
|
|
333
|
+
* query().
|
|
297
334
|
*/
|
|
298
335
|
async function query(ds, sparql, options) {
|
|
299
336
|
assertFnDataset(ds, 'query');
|
|
300
|
-
const result = await engineApi.query(
|
|
301
|
-
return result instanceof Dataset ?
|
|
337
|
+
const result = await engineApi.query((await engineOf(ds)), sparql, options);
|
|
338
|
+
return result instanceof engineApi.Dataset ? wrapEngine(result) : result;
|
|
302
339
|
}
|
|
303
340
|
|
|
304
341
|
/**
|
|
305
342
|
* Materialize an entailment closure as a new FnDataset.
|
|
306
343
|
*
|
|
307
|
-
* Reuses query()'s
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
* CONSTRUCT at all, so "CONSTRUCT ... WHERE ... { entail }" is not
|
|
312
|
-
* reachable through the existing API today. Instead this runs
|
|
313
|
-
* `SELECT ?s ?p ?o WHERE { ?s ?p ?o }` with the entailment option
|
|
314
|
-
* (exactly the combination test/api.test.js's "query: entail RDFS
|
|
315
|
-
* infers subclass instances" already exercises) and repackages each
|
|
316
|
-
* solution row as a quad — pure JS reshaping of already-materialized
|
|
317
|
-
* bindings, not new RDF/SPARQL semantics, so it works with the CLI
|
|
318
|
-
* bundle alone (no npm-entry bundle required).
|
|
344
|
+
* Reuses query()'s entailment support: it runs
|
|
345
|
+
* `SELECT ?s ?p ?o WHERE { ?s ?p ?o }` with the entailment option (the
|
|
346
|
+
* engine closes the default graph under the regime, then answers the
|
|
347
|
+
* query; op queryRaw) and repackages each solution row as a quad.
|
|
319
348
|
*
|
|
320
349
|
* Scope limitation (documented, not silent): like a bare
|
|
321
350
|
* `WHERE { ?s ?p ?o }` in SPARQL generally, this closes over the
|
|
@@ -326,10 +355,10 @@ async function query(ds, sparql, options) {
|
|
|
326
355
|
*/
|
|
327
356
|
// Case-insensitive regime aliases ('rdfs', 'owl-rl', 'owlrl', 'owl_rl')
|
|
328
357
|
// normalized to the engine's exact-case ENTAIL_VALUES spelling ('RDFS',
|
|
329
|
-
// 'OWL-RL'); anything else (including already-correct casing, or a
|
|
330
|
-
//
|
|
331
|
-
//
|
|
332
|
-
//
|
|
358
|
+
// 'OWL-RL'); anything else (including already-correct casing, or a value
|
|
359
|
+
// that names no regime) passes through unchanged, so engineApi.query's own
|
|
360
|
+
// validation reports the error and this function does not guess what the
|
|
361
|
+
// caller meant.
|
|
333
362
|
const ENTAIL_REGIME_ALIASES = {
|
|
334
363
|
none: 'none', rdfs: 'RDFS', 'owl-rl': 'OWL-RL', owlrl: 'OWL-RL', owl_rl: 'OWL-RL',
|
|
335
364
|
};
|
|
@@ -380,15 +409,14 @@ function rejectIklRegime(regime, who) {
|
|
|
380
409
|
async function entail(ds, regime) {
|
|
381
410
|
assertFnDataset(ds, 'entail');
|
|
382
411
|
rejectIklRegime(regime, 'entail');
|
|
383
|
-
const rows = await engineApi.query(
|
|
384
|
-
toDataset(ds), 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }',
|
|
412
|
+
const rows = await engineApi.query((await engineOf(ds)), 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }',
|
|
385
413
|
{ entail: normalizeEntailRegime(regime) });
|
|
386
414
|
return makeFnDataset(
|
|
387
415
|
rows.map((row) => dataFactory.quad(row.get('s'), row.get('p'), row.get('o'))));
|
|
388
416
|
}
|
|
389
417
|
|
|
390
418
|
/**
|
|
391
|
-
* SHACL Core validation.
|
|
419
|
+
* SHACL Core validation. Neither
|
|
392
420
|
* argument is mutated or consumed -- both stay valid FnDatasets after
|
|
393
421
|
* the call, same as every other op in this module.
|
|
394
422
|
*
|
|
@@ -401,13 +429,13 @@ async function entail(ds, regime) {
|
|
|
401
429
|
async function validate(ds, shapes) {
|
|
402
430
|
assertFnDataset(ds, 'validate');
|
|
403
431
|
assertFnDataset(shapes, 'validate');
|
|
404
|
-
const r = await engineApi.shaclValidate(
|
|
405
|
-
return { conforms: r.conforms, report:
|
|
432
|
+
const r = await engineApi.shaclValidate((await engineOf(ds)), (await engineOf(shapes)));
|
|
433
|
+
return { conforms: r.conforms, report: wrapEngine(r.report) };
|
|
406
434
|
}
|
|
407
435
|
|
|
408
436
|
/**
|
|
409
437
|
* ShEx (Shape Expressions) validation of one focus node against one
|
|
410
|
-
* shape.
|
|
438
|
+
* shape.
|
|
411
439
|
*
|
|
412
440
|
* @param {FnDataset} ds the data graph
|
|
413
441
|
* @param {string} schema ShExJ (JSON Schema form), as text
|
|
@@ -420,14 +448,13 @@ async function validate(ds, shapes) {
|
|
|
420
448
|
*/
|
|
421
449
|
async function shex(ds, schema, focus, shape) {
|
|
422
450
|
assertFnDataset(ds, 'shex');
|
|
423
|
-
return engineApi.shexValidate(
|
|
451
|
+
return engineApi.shexValidate((await engineOf(ds)), schema, focus, shape);
|
|
424
452
|
}
|
|
425
453
|
|
|
426
454
|
/**
|
|
427
455
|
* Evaluate an RML mapping graph against one logical source's raw
|
|
428
|
-
* data, materializing the generated triples as a new FnDataset.
|
|
429
|
-
*
|
|
430
|
-
* every triples map in `mapping` reads the SAME `source` -- joins
|
|
456
|
+
* data, materializing the generated triples as a new FnDataset. Every
|
|
457
|
+
* triples map in `mapping` reads the SAME `source` -- joins
|
|
431
458
|
* across two different logical sources are not reachable through this
|
|
432
459
|
* one-source entry point (see engineApi.rmlMap's doc comment).
|
|
433
460
|
*
|
|
@@ -438,13 +465,13 @@ async function shex(ds, schema, focus, shape) {
|
|
|
438
465
|
*/
|
|
439
466
|
async function fromMapping(mapping, source, kind) {
|
|
440
467
|
assertFnDataset(mapping, 'fromMapping');
|
|
441
|
-
return
|
|
468
|
+
return wrapEngine(await engineApi.rmlMap((await engineOf(mapping)), source, kind));
|
|
442
469
|
}
|
|
443
470
|
|
|
444
471
|
/**
|
|
445
472
|
* CSVW csv2rdf conversion (w3.org/TR/csv2rdf): convert raw tabular
|
|
446
473
|
* data plus an optional CSVW metadata document into a new FnDataset.
|
|
447
|
-
*
|
|
474
|
+
* Unlike fromMapping there is no
|
|
448
475
|
* FnDataset input -- both arguments are raw text (CSVW's metadata
|
|
449
476
|
* format is JSON, not RDF). Scope cut (documented, not silent --
|
|
450
477
|
* mirrors fromMapping's one-source cut): every table in a multi-table
|
|
@@ -461,14 +488,13 @@ async function fromMapping(mapping, source, kind) {
|
|
|
461
488
|
* @returns {Promise<FnDataset>}
|
|
462
489
|
*/
|
|
463
490
|
async function fromCsvw(csv, metadata, options) {
|
|
464
|
-
return
|
|
491
|
+
return wrapEngine(await engineApi.csvwToRdf(csv, metadata, options));
|
|
465
492
|
}
|
|
466
493
|
|
|
467
494
|
/**
|
|
468
495
|
* RIF Core forward-chaining saturation, materialized as a new
|
|
469
496
|
* FnDataset (input triples + derived triples, default graph only --
|
|
470
|
-
* RIF Core has no named-graph notion).
|
|
471
|
-
* bundle.
|
|
497
|
+
* RIF Core has no named-graph notion).
|
|
472
498
|
*
|
|
473
499
|
* @param {FnDataset} ds the premise graph
|
|
474
500
|
* @param {string} rules a RIF Core XML rule document
|
|
@@ -476,7 +502,7 @@ async function fromCsvw(csv, metadata, options) {
|
|
|
476
502
|
*/
|
|
477
503
|
async function rif(ds, rules) {
|
|
478
504
|
assertFnDataset(ds, 'rif');
|
|
479
|
-
return
|
|
505
|
+
return wrapEngine(await engineApi.rifEval((await engineOf(ds)), rules));
|
|
480
506
|
}
|
|
481
507
|
|
|
482
508
|
/**
|
|
@@ -489,8 +515,7 @@ async function rif(ds, rules) {
|
|
|
489
515
|
* Gutierrez, "Simple and Efficient Minimal RDFS", J. Web Semantics
|
|
490
516
|
* 7(3), 2009). Mirrors engineApi.coreRdfsClosure's `{ok, ntriples}`
|
|
491
517
|
* result, with `ntriples` parsed into an FnDataset via
|
|
492
|
-
* Dataset
|
|
493
|
-
* npm-entry engine bundle. `rhoDfClosure` is kept below as a
|
|
518
|
+
* the engine Dataset of the closure. `rhoDfClosure` is kept below as a
|
|
494
519
|
* literature-name alias.
|
|
495
520
|
* @param {FnDataset} ds
|
|
496
521
|
* @param {{format?: string}} [options]
|
|
@@ -498,17 +523,15 @@ async function rif(ds, rules) {
|
|
|
498
523
|
*/
|
|
499
524
|
async function coreRdfsClosure(ds, options) {
|
|
500
525
|
assertFnDataset(ds, 'coreRdfsClosure');
|
|
501
|
-
const r = await engineApi.coreRdfsClosure(
|
|
502
|
-
return { ok:
|
|
526
|
+
const r = await engineApi.coreRdfsClosure((await engineOf(ds)), options);
|
|
527
|
+
return { ok: true, dataset: wrapEngine(r) };
|
|
503
528
|
}
|
|
504
529
|
/** Literature-name alias for coreRdfsClosure (ρdf; see above). */
|
|
505
530
|
const rhoDfClosure = coreRdfsClosure;
|
|
506
531
|
|
|
507
532
|
/**
|
|
508
|
-
* Decidable core-RDFS fragment check (`
|
|
509
|
-
*
|
|
510
|
-
* certified coreRdfsClosure guarantee apply to `ds`? Needs the
|
|
511
|
-
* npm-entry engine bundle. `rhoDfFragmentCheck` is kept below as a
|
|
533
|
+
* Decidable core-RDFS fragment check (L4Factoidal/RDFS, `isRhoDfFrag`):
|
|
534
|
+
* is `ds` in the core-RDFS fragment coreRdfsClosure is defined for? `rhoDfFragmentCheck` is kept below as a
|
|
512
535
|
* literature-name alias.
|
|
513
536
|
* @param {FnDataset} ds
|
|
514
537
|
* @param {{format?: string}} [options]
|
|
@@ -516,7 +539,7 @@ const rhoDfClosure = coreRdfsClosure;
|
|
|
516
539
|
*/
|
|
517
540
|
async function coreRdfsCheck(ds, options) {
|
|
518
541
|
assertFnDataset(ds, 'coreRdfsCheck');
|
|
519
|
-
return engineApi.coreRdfsCheck(
|
|
542
|
+
return engineApi.coreRdfsCheck((await engineOf(ds)), options);
|
|
520
543
|
}
|
|
521
544
|
/** Literature-name alias for coreRdfsCheck (ρdf; see above). */
|
|
522
545
|
const rhoDfFragmentCheck = coreRdfsCheck;
|
|
@@ -529,19 +552,17 @@ const rhoDfFragmentCheck = coreRdfsCheck;
|
|
|
529
552
|
* Allemang & Hendler 2008; "RDFS++", AllegroGraph). Every OWL row
|
|
530
553
|
* carries a proved licensing + truth lemma; no chain-level
|
|
531
554
|
* completeness claim (theorem registry) — weaker than
|
|
532
|
-
* coreRdfsClosure's decides-iff guarantee.
|
|
533
|
-
* bundle.
|
|
555
|
+
* coreRdfsClosure's decides-iff guarantee.
|
|
534
556
|
* @param {FnDataset} ds
|
|
535
557
|
* @param {{format?: string}} [options]
|
|
536
|
-
* @returns {Promise<{ok: boolean, dataset: FnDataset
|
|
558
|
+
* @returns {Promise<{ok: boolean, dataset: FnDataset}>}
|
|
537
559
|
*/
|
|
538
560
|
async function rdfsPlusClosure(ds, options) {
|
|
539
561
|
assertFnDataset(ds, 'rdfsPlusClosure');
|
|
540
|
-
const r = await engineApi.rdfsPlusClosure(
|
|
562
|
+
const r = await engineApi.rdfsPlusClosure((await engineOf(ds)), options);
|
|
541
563
|
return {
|
|
542
|
-
ok:
|
|
543
|
-
dataset:
|
|
544
|
-
rounds: r.rounds,
|
|
564
|
+
ok: true,
|
|
565
|
+
dataset: wrapEngine(r),
|
|
545
566
|
};
|
|
546
567
|
}
|
|
547
568
|
|
|
@@ -551,7 +572,7 @@ async function rdfsPlusClosure(ds, options) {
|
|
|
551
572
|
* individual the model-construction reasoner proves is a member of an
|
|
552
573
|
* OWL class expression (someValuesFrom / hasValue / unionOf /
|
|
553
574
|
* intersectionOf, and the named class an equivalentClass restriction
|
|
554
|
-
* defines).
|
|
575
|
+
* defines). Default graph only.
|
|
555
576
|
*
|
|
556
577
|
* @param {FnDataset} ds the ontology + ABox graph
|
|
557
578
|
* @returns {Promise<{dataset: FnDataset, addedCount: number}>} dataset
|
|
@@ -560,31 +581,29 @@ async function rdfsPlusClosure(ds, options) {
|
|
|
560
581
|
*/
|
|
561
582
|
async function tableauMaterialise(ds) {
|
|
562
583
|
assertFnDataset(ds, 'tableauMaterialise');
|
|
563
|
-
const r = await engineApi.tableauMaterialise(
|
|
564
|
-
return { dataset:
|
|
584
|
+
const r = await engineApi.tableauMaterialise((await engineOf(ds)));
|
|
585
|
+
return { dataset: wrapEngine(r.dataset), addedCount: r.addedCount };
|
|
565
586
|
}
|
|
566
587
|
|
|
567
588
|
/**
|
|
568
589
|
* OWL DL inconsistency verdict (bin/owl-runner's DL pipeline: OWL-RL
|
|
569
590
|
* closure -> tableau materialise -> OWL-RL closure -> is_inconsistent).
|
|
570
591
|
* `rlAlone` is the plain OWL-RL verdict on the same input, so a caller
|
|
571
|
-
* can see the cases the tableau adds.
|
|
572
|
-
* bundle. Default graph only.
|
|
592
|
+
* can see the cases the tableau adds. Default graph only.
|
|
573
593
|
*
|
|
574
594
|
* @param {FnDataset} ds the ontology + ABox graph
|
|
575
595
|
* @returns {Promise<{inconsistent: boolean, rlAlone: boolean}>}
|
|
576
596
|
*/
|
|
577
597
|
async function tableauDlInconsistent(ds) {
|
|
578
598
|
assertFnDataset(ds, 'tableauDlInconsistent');
|
|
579
|
-
return engineApi.tableauDlInconsistent(
|
|
599
|
+
return engineApi.tableauDlInconsistent((await engineOf(ds)));
|
|
580
600
|
}
|
|
581
601
|
|
|
582
602
|
/**
|
|
583
603
|
* OWL DL consistency verdict via the verified clash-detecting tableau
|
|
584
604
|
* (formal/fstar/Tableau.Refute.fst's `tableau_consistent` over the
|
|
585
605
|
* OWL-RL closure -- the pure verified chain bin/owl-runner runs under
|
|
586
|
-
* `--regime dl`, minus its native-only z3 oracle).
|
|
587
|
-
* bundle. Default graph only.
|
|
606
|
+
* `--regime dl`, minus its native-only z3 oracle). Default graph only.
|
|
588
607
|
*
|
|
589
608
|
* `consistent` is three-valued: `false` (a clash on every tableau
|
|
590
609
|
* branch), `true` (a model was constructed), or `null` -- the refuter
|
|
@@ -597,7 +616,7 @@ async function tableauDlInconsistent(ds) {
|
|
|
597
616
|
* @returns {Promise<{consistent: boolean|null, reason?: string}>}
|
|
598
617
|
*/
|
|
599
618
|
async function owlIsConsistent(ontology, options) {
|
|
600
|
-
const data = ontology instanceof FnDataset ?
|
|
619
|
+
const data = ontology instanceof FnDataset ? (await engineOf(ontology)) : ontology;
|
|
601
620
|
return engineApi.owlIsConsistent(data, options);
|
|
602
621
|
}
|
|
603
622
|
|
|
@@ -605,7 +624,7 @@ async function owlIsConsistent(ontology, options) {
|
|
|
605
624
|
* OWL entailment check: does `premise` entail `conclusion`? Verified
|
|
606
625
|
* two-path dispatch (`via: "closure"` for the OWL-RL closure path,
|
|
607
626
|
* `via: "refutation"` for negate-and-refute), mirroring bin/owl-runner.
|
|
608
|
-
*
|
|
627
|
+
* Default graph only. `entailed` is
|
|
609
628
|
* three-valued (`true` / `false` / `null` budget-out, `reason` names the
|
|
610
629
|
* cap).
|
|
611
630
|
*
|
|
@@ -615,20 +634,20 @@ async function owlIsConsistent(ontology, options) {
|
|
|
615
634
|
* @returns {Promise<{entailed: boolean|null, via: 'closure'|'refutation', reason?: string}>}
|
|
616
635
|
*/
|
|
617
636
|
async function owlEntails(premise, conclusion, options) {
|
|
618
|
-
const p = premise instanceof FnDataset ?
|
|
619
|
-
const c = conclusion instanceof FnDataset ?
|
|
637
|
+
const p = premise instanceof FnDataset ? (await engineOf(premise)) : premise;
|
|
638
|
+
const c = conclusion instanceof FnDataset ? (await engineOf(conclusion)) : conclusion;
|
|
620
639
|
return engineApi.owlEntails(p, c, options);
|
|
621
640
|
}
|
|
622
641
|
|
|
623
642
|
/**
|
|
624
|
-
* RDFC-1.0 canonicalization: canonical N-Quads text.
|
|
625
|
-
*
|
|
643
|
+
* RDFC-1.0 canonicalization: canonical N-Quads text (index.js's
|
|
644
|
+
* canonicalize()).
|
|
626
645
|
*/
|
|
627
646
|
async function canonicalize(ds) {
|
|
628
647
|
assertFnDataset(ds, 'canonicalize');
|
|
629
648
|
let cached = CANON_CACHE.get(ds);
|
|
630
649
|
if (cached === undefined) {
|
|
631
|
-
const p = engineApi.canonicalize(
|
|
650
|
+
const p = engineApi.canonicalize((await engineOf(ds))).then((text) => {
|
|
632
651
|
CANON_CACHE.set(ds, text); // replace the in-flight promise
|
|
633
652
|
return text;
|
|
634
653
|
});
|
|
@@ -719,60 +738,6 @@ async function equals(a, b) {
|
|
|
719
738
|
return h1 === h2;
|
|
720
739
|
}
|
|
721
740
|
|
|
722
|
-
/**
|
|
723
|
-
* Open a COTTAS/Parquet artifact's raw bytes as a queryable, read-only
|
|
724
|
-
* store (docs/designissues/2026-07-06-inmemory-bytes-store.md, browser
|
|
725
|
-
* call site). Needs the npm-entry engine bundle. Unlike every other
|
|
726
|
-
* constructor in this module, the returned object is NOT an FnDataset:
|
|
727
|
-
* the whole point of the design is that rows decode lazily as a query
|
|
728
|
-
* touches them, never materializing the corpus into heap FnDataset
|
|
729
|
-
* quads (measured 64-161 B/quad vs. an FnDataset/heap Dataset's
|
|
730
|
-
* ~877 B/quad for the same data, in the design doc's native numbers).
|
|
731
|
-
*
|
|
732
|
-
* @param {string|Uint8Array|ArrayBuffer} bytes whole `.cottas` file contents
|
|
733
|
-
* @returns {Promise<{handle: string,
|
|
734
|
-
* query: (sparql: string) => Promise<Array<Map<string,object>>|boolean|FnDataset>,
|
|
735
|
-
* close: () => Promise<void>}>}
|
|
736
|
-
* query() divergences from fn.query() (documented, not silent): no
|
|
737
|
-
* entail option, no write/--delta-log overlay (read-only), and a
|
|
738
|
-
* query shape the backend executor can't push down rejects instead
|
|
739
|
-
* of silently falling back to a full materialize (see
|
|
740
|
-
* engineApi.queryCottas's doc comment). CONSTRUCT still returns an
|
|
741
|
-
* FnDataset (materialized once for that query only).
|
|
742
|
-
*/
|
|
743
|
-
async function openCottas(bytes) {
|
|
744
|
-
const handle = await engineApi.openCottas(bytes);
|
|
745
|
-
let closed = false;
|
|
746
|
-
return {
|
|
747
|
-
handle,
|
|
748
|
-
async query(sparql) {
|
|
749
|
-
if (closed) throw new Error('openCottas store: query() called after close()');
|
|
750
|
-
const result = await engineApi.queryCottas(handle, sparql);
|
|
751
|
-
return result instanceof Dataset ? fromDataset(result) : result;
|
|
752
|
-
},
|
|
753
|
-
async close() {
|
|
754
|
-
if (closed) return;
|
|
755
|
-
closed = true;
|
|
756
|
-
await engineApi.closeCottas(handle);
|
|
757
|
-
},
|
|
758
|
-
};
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
/**
|
|
762
|
-
* Serialize an FnDataset to COTTAS/Parquet bytes via the native writer
|
|
763
|
-
* (the same pure `Tot` F* function `factoidal compact --native-writer`
|
|
764
|
-
* uses). Needs the npm-entry engine bundle. Round-trips through
|
|
765
|
-
* openCottas(): feeding the result straight back into openCottas()
|
|
766
|
-
* reproduces the same queryable store.
|
|
767
|
-
*
|
|
768
|
-
* @param {FnDataset} ds
|
|
769
|
-
* @returns {Promise<Uint8Array>}
|
|
770
|
-
*/
|
|
771
|
-
async function toCottas(ds) {
|
|
772
|
-
assertFnDataset(ds, 'toCottas');
|
|
773
|
-
return engineApi.toCottas(toDataset(ds));
|
|
774
|
-
}
|
|
775
|
-
|
|
776
741
|
/**
|
|
777
742
|
* Enumerate named graphs (default graph excluded), first-seen order.
|
|
778
743
|
* Reuses index.js's graphs() enumeration; wraps each per-graph
|
|
@@ -780,8 +745,11 @@ async function toCottas(ds) {
|
|
|
780
745
|
*/
|
|
781
746
|
function graphs(ds) {
|
|
782
747
|
assertFnDataset(ds, 'graphs');
|
|
783
|
-
|
|
784
|
-
|
|
748
|
+
const seen = new Map();
|
|
749
|
+
for (const q of ds) {
|
|
750
|
+
if (q.graph.termType !== 'DefaultGraph' && !seen.has(q.graph.value)) seen.set(q.graph.value, q.graph);
|
|
751
|
+
}
|
|
752
|
+
return [...seen].map(([iri, g]) => [iri, ds.match(null, null, null, g)]);
|
|
785
753
|
}
|
|
786
754
|
|
|
787
755
|
// ---------------------------------------------------------------------
|
|
@@ -860,7 +828,7 @@ function pipe(...fns) {
|
|
|
860
828
|
// -----------------------------------------------------------------
|
|
861
829
|
// Typed engine functions (#74). Re-exported unchanged from the JS
|
|
862
830
|
// engine api — each is already a pure, value-in / value-out function
|
|
863
|
-
// over one
|
|
831
|
+
// over one engine op (XSLT, MathML, XForms, JSON Schema,
|
|
864
832
|
// Schematron, TOAN CAS, matrix algebra), so they belong in the
|
|
865
833
|
// functional surface as-is. See index.d.ts / fn.d.ts for signatures.
|
|
866
834
|
// -----------------------------------------------------------------
|
|
@@ -875,12 +843,6 @@ const {
|
|
|
875
843
|
toanSimplify,
|
|
876
844
|
toanDiff,
|
|
877
845
|
toanSubst,
|
|
878
|
-
matrixDeterminant,
|
|
879
|
-
matrixScalarProduct,
|
|
880
|
-
matrixVectorProduct,
|
|
881
|
-
matrixOuterProduct,
|
|
882
|
-
sigmoidPoints,
|
|
883
|
-
sigmoidFormulaMathml,
|
|
884
846
|
vcSha256Hex,
|
|
885
847
|
vcEd25519SecretToPublic,
|
|
886
848
|
vcEd25519Sign,
|
|
@@ -921,8 +883,6 @@ module.exports = {
|
|
|
921
883
|
canonicalize,
|
|
922
884
|
hash,
|
|
923
885
|
equals,
|
|
924
|
-
openCottas,
|
|
925
|
-
toCottas,
|
|
926
886
|
graphs,
|
|
927
887
|
cell,
|
|
928
888
|
derive,
|
|
@@ -938,12 +898,6 @@ module.exports = {
|
|
|
938
898
|
toanSimplify,
|
|
939
899
|
toanDiff,
|
|
940
900
|
toanSubst,
|
|
941
|
-
matrixDeterminant,
|
|
942
|
-
matrixScalarProduct,
|
|
943
|
-
matrixVectorProduct,
|
|
944
|
-
matrixOuterProduct,
|
|
945
|
-
sigmoidPoints,
|
|
946
|
-
sigmoidFormulaMathml,
|
|
947
901
|
vcSha256Hex,
|
|
948
902
|
vcEd25519SecretToPublic,
|
|
949
903
|
vcEd25519Sign,
|