@factoidal/core 0.7.0 → 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.
Files changed (193) hide show
  1. package/CHANGELOG.md +510 -1
  2. package/NOTICE +2 -21
  3. package/README.md +117 -993
  4. package/api.d.ts +53 -0
  5. package/api.js +5 -0
  6. package/api.mjs +56 -0
  7. package/bin/engine.mjs +38 -19
  8. package/bin/factoidal.mjs +513 -67
  9. package/bin/pack.mjs +37 -0
  10. package/bin/serve-worker.mjs +32 -0
  11. package/bin/serve.mjs +423 -0
  12. package/bin/store-worker-host.mjs +1 -1
  13. package/bin/store.mjs +1 -1
  14. package/browser.d.ts +110 -507
  15. package/browser.js +151 -2257
  16. package/docs/fuseki-replacement.md +108 -0
  17. package/fn.d.ts +24 -95
  18. package/fn.js +104 -150
  19. package/index.d.ts +598 -259
  20. package/index.js +4 -234
  21. package/index.mjs +176 -84
  22. package/l4-assets/l4factoidal.js +47 -7
  23. package/l4-assets/l4factoidal.mjs +1 -1
  24. package/l4-assets/l4factoidal.wasm +0 -0
  25. package/l4-assets/version.json +11 -7
  26. package/lib/api.mjs +2300 -0
  27. package/lib/browser-engine.mjs +69 -0
  28. package/lib/dataset.mjs +377 -0
  29. package/lib/delta-log-hosts.mjs +191 -0
  30. package/lib/lean-entry.mjs +204 -0
  31. package/lib/pure.mjs +98 -0
  32. package/lib/store.mjs +115 -0
  33. package/lib/version.mjs +5 -0
  34. package/lws/README.md +97 -0
  35. package/lws/server.mjs +331 -0
  36. package/package.json +59 -61
  37. package/rdfjs.js +5 -536
  38. package/rdfjs.mjs +594 -0
  39. package/sample-store.d.ts +8 -16
  40. package/sample-store.mjs +39 -29
  41. package/solid/client/README.md +100 -0
  42. package/solid/client/index.mjs +277 -0
  43. package/solid/server/README.md +96 -0
  44. package/solid/server/index.mjs +317 -0
  45. package/store-host/deno.mjs +8 -0
  46. package/store-host/index.mjs +12 -0
  47. package/store-host/node.mjs +8 -0
  48. package/xmpp/README.md +107 -0
  49. package/xmpp/index.mjs +229 -0
  50. package/browser-wasm.js +0 -872
  51. package/factoidal-npm-entry.js +0 -15477
  52. package/factoidal-npm-entry.wasm.assets/code-5a7fc68f2ab1323718b8.wasm +0 -0
  53. package/factoidal-npm-entry.wasm.js +0 -455
  54. package/factoidal.js +0 -13118
  55. package/factoidal.wasm.assets/code-bbe6099bfb5b10c4c3ab.wasm +0 -0
  56. package/factoidal.wasm.js +0 -457
  57. package/hacl-init.js +0 -92
  58. package/hacl-wasm/FStar.wasm +0 -0
  59. package/hacl-wasm/Hacl_Bignum.wasm +0 -0
  60. package/hacl-wasm/Hacl_Bignum25519_51.wasm +0 -0
  61. package/hacl-wasm/Hacl_Bignum_Base.wasm +0 -0
  62. package/hacl-wasm/Hacl_Curve25519_51.wasm +0 -0
  63. package/hacl-wasm/Hacl_Ed25519.wasm +0 -0
  64. package/hacl-wasm/Hacl_Ed25519_PrecompTable.wasm +0 -0
  65. package/hacl-wasm/Hacl_Hash_Base.wasm +0 -0
  66. package/hacl-wasm/Hacl_Hash_SHA2.wasm +0 -0
  67. package/hacl-wasm/Hacl_IntTypes_Intrinsics.wasm +0 -0
  68. package/hacl-wasm/LowStar_Endianness.wasm +0 -0
  69. package/hacl-wasm/WasmSupport.wasm +0 -0
  70. package/hacl-wasm/api.js +0 -775
  71. package/hacl-wasm/api.json +0 -3787
  72. package/hacl-wasm/layouts.json +0 -1
  73. package/hacl-wasm/loader.js +0 -568
  74. package/hacl-wasm/shell.js +0 -12
  75. package/l4-core.d.ts +0 -159
  76. package/l4-core.js +0 -188
  77. package/l4.d.ts +0 -50
  78. package/l4.js +0 -104
  79. package/lib/api.js +0 -2300
  80. package/lib/engine-js.js +0 -165
  81. package/lib/engine-wasm.js +0 -300
  82. package/sample-store/CURRENT +0 -1
  83. package/sample-store/gen-1/manifest.sbm2 +0 -0
  84. package/sample-store/gen-1/manifest.tsv +0 -14
  85. package/sample-store/gen-1/predicate-0.ibk3 +0 -0
  86. package/sample-store/gen-1/predicate-0.ibk3.merkle +0 -1
  87. package/sample-store/gen-1/predicate-0.ibk3.oli2 +0 -0
  88. package/sample-store/gen-1/predicate-0.ibk3.oli2.merkle +0 -1
  89. package/sample-store/gen-1/predicate-0.ibk3.sri2 +0 -0
  90. package/sample-store/gen-1/predicate-0.ibk3.sri2.merkle +0 -1
  91. package/sample-store/gen-1/predicate-0.ibk3.tli1 +0 -0
  92. package/sample-store/gen-1/predicate-0.ibk3.tli1.merkle +0 -0
  93. package/sample-store/gen-1/predicate-1.ibk3 +0 -0
  94. package/sample-store/gen-1/predicate-1.ibk3.merkle +0 -0
  95. package/sample-store/gen-1/predicate-1.ibk3.oli2 +0 -0
  96. package/sample-store/gen-1/predicate-1.ibk3.oli2.merkle +0 -0
  97. package/sample-store/gen-1/predicate-1.ibk3.sri2 +0 -0
  98. package/sample-store/gen-1/predicate-1.ibk3.sri2.merkle +0 -1
  99. package/sample-store/gen-1/predicate-1.ibk3.tli1 +0 -0
  100. package/sample-store/gen-1/predicate-1.ibk3.tli1.merkle +0 -1
  101. package/sample-store/gen-1/predicate-10.ibk3 +0 -0
  102. package/sample-store/gen-1/predicate-10.ibk3.merkle +0 -1
  103. package/sample-store/gen-1/predicate-10.ibk3.oli2 +0 -0
  104. package/sample-store/gen-1/predicate-10.ibk3.oli2.merkle +0 -0
  105. package/sample-store/gen-1/predicate-10.ibk3.sri2 +0 -0
  106. package/sample-store/gen-1/predicate-10.ibk3.sri2.merkle +0 -1
  107. package/sample-store/gen-1/predicate-10.ibk3.tli1 +0 -0
  108. package/sample-store/gen-1/predicate-10.ibk3.tli1.merkle +0 -1
  109. package/sample-store/gen-1/predicate-11.ibk3 +0 -0
  110. package/sample-store/gen-1/predicate-11.ibk3.merkle +0 -0
  111. package/sample-store/gen-1/predicate-11.ibk3.oli2 +0 -0
  112. package/sample-store/gen-1/predicate-11.ibk3.oli2.merkle +0 -1
  113. package/sample-store/gen-1/predicate-11.ibk3.sri2 +0 -0
  114. package/sample-store/gen-1/predicate-11.ibk3.sri2.merkle +0 -1
  115. package/sample-store/gen-1/predicate-11.ibk3.tli1 +0 -0
  116. package/sample-store/gen-1/predicate-11.ibk3.tli1.merkle +0 -1
  117. package/sample-store/gen-1/predicate-12.ibk3 +0 -0
  118. package/sample-store/gen-1/predicate-12.ibk3.merkle +0 -1
  119. package/sample-store/gen-1/predicate-12.ibk3.oli2 +0 -0
  120. package/sample-store/gen-1/predicate-12.ibk3.oli2.merkle +0 -1
  121. package/sample-store/gen-1/predicate-12.ibk3.sri2 +0 -0
  122. package/sample-store/gen-1/predicate-12.ibk3.sri2.merkle +0 -1
  123. package/sample-store/gen-1/predicate-12.ibk3.tli1 +0 -0
  124. package/sample-store/gen-1/predicate-12.ibk3.tli1.merkle +0 -1
  125. package/sample-store/gen-1/predicate-2.ibk3 +0 -0
  126. package/sample-store/gen-1/predicate-2.ibk3.merkle +0 -1
  127. package/sample-store/gen-1/predicate-2.ibk3.oli2 +0 -0
  128. package/sample-store/gen-1/predicate-2.ibk3.oli2.merkle +0 -1
  129. package/sample-store/gen-1/predicate-2.ibk3.sri2 +0 -0
  130. package/sample-store/gen-1/predicate-2.ibk3.sri2.merkle +0 -0
  131. package/sample-store/gen-1/predicate-2.ibk3.tli1 +0 -0
  132. package/sample-store/gen-1/predicate-2.ibk3.tli1.merkle +0 -0
  133. package/sample-store/gen-1/predicate-3.ibk3 +0 -0
  134. package/sample-store/gen-1/predicate-3.ibk3.merkle +0 -1
  135. package/sample-store/gen-1/predicate-3.ibk3.oli2 +0 -0
  136. package/sample-store/gen-1/predicate-3.ibk3.oli2.merkle +0 -1
  137. package/sample-store/gen-1/predicate-3.ibk3.sri2 +0 -0
  138. package/sample-store/gen-1/predicate-3.ibk3.sri2.merkle +0 -1
  139. package/sample-store/gen-1/predicate-3.ibk3.tli1 +0 -0
  140. package/sample-store/gen-1/predicate-3.ibk3.tli1.merkle +0 -1
  141. package/sample-store/gen-1/predicate-4.ibk3 +0 -0
  142. package/sample-store/gen-1/predicate-4.ibk3.merkle +0 -0
  143. package/sample-store/gen-1/predicate-4.ibk3.oli2 +0 -0
  144. package/sample-store/gen-1/predicate-4.ibk3.oli2.merkle +0 -1
  145. package/sample-store/gen-1/predicate-4.ibk3.sri2 +0 -0
  146. package/sample-store/gen-1/predicate-4.ibk3.sri2.merkle +0 -1
  147. package/sample-store/gen-1/predicate-4.ibk3.tli1 +0 -0
  148. package/sample-store/gen-1/predicate-4.ibk3.tli1.merkle +0 -2
  149. package/sample-store/gen-1/predicate-5.ibk3 +0 -0
  150. package/sample-store/gen-1/predicate-5.ibk3.merkle +0 -1
  151. package/sample-store/gen-1/predicate-5.ibk3.oli2 +0 -0
  152. package/sample-store/gen-1/predicate-5.ibk3.oli2.merkle +0 -1
  153. package/sample-store/gen-1/predicate-5.ibk3.sri2 +0 -0
  154. package/sample-store/gen-1/predicate-5.ibk3.sri2.merkle +0 -1
  155. package/sample-store/gen-1/predicate-5.ibk3.tli1 +0 -0
  156. package/sample-store/gen-1/predicate-5.ibk3.tli1.merkle +0 -1
  157. package/sample-store/gen-1/predicate-6.ibk3 +0 -0
  158. package/sample-store/gen-1/predicate-6.ibk3.merkle +0 -1
  159. package/sample-store/gen-1/predicate-6.ibk3.oli2 +0 -0
  160. package/sample-store/gen-1/predicate-6.ibk3.oli2.merkle +0 -1
  161. package/sample-store/gen-1/predicate-6.ibk3.sri2 +0 -0
  162. package/sample-store/gen-1/predicate-6.ibk3.sri2.merkle +0 -1
  163. package/sample-store/gen-1/predicate-6.ibk3.tli1 +0 -0
  164. package/sample-store/gen-1/predicate-6.ibk3.tli1.merkle +0 -0
  165. package/sample-store/gen-1/predicate-7.ibk3 +0 -0
  166. package/sample-store/gen-1/predicate-7.ibk3.merkle +0 -0
  167. package/sample-store/gen-1/predicate-7.ibk3.oli2 +0 -0
  168. package/sample-store/gen-1/predicate-7.ibk3.oli2.merkle +0 -2
  169. package/sample-store/gen-1/predicate-7.ibk3.sri2 +0 -0
  170. package/sample-store/gen-1/predicate-7.ibk3.sri2.merkle +0 -1
  171. package/sample-store/gen-1/predicate-7.ibk3.tli1 +0 -0
  172. package/sample-store/gen-1/predicate-7.ibk3.tli1.merkle +0 -1
  173. package/sample-store/gen-1/predicate-8.ibk3 +0 -0
  174. package/sample-store/gen-1/predicate-8.ibk3.merkle +0 -1
  175. package/sample-store/gen-1/predicate-8.ibk3.oli2 +0 -0
  176. package/sample-store/gen-1/predicate-8.ibk3.oli2.merkle +0 -1
  177. package/sample-store/gen-1/predicate-8.ibk3.sri2 +0 -0
  178. package/sample-store/gen-1/predicate-8.ibk3.sri2.merkle +0 -1
  179. package/sample-store/gen-1/predicate-8.ibk3.tli1 +0 -0
  180. package/sample-store/gen-1/predicate-8.ibk3.tli1.merkle +0 -1
  181. package/sample-store/gen-1/predicate-9.ibk3 +0 -0
  182. package/sample-store/gen-1/predicate-9.ibk3.merkle +0 -1
  183. package/sample-store/gen-1/predicate-9.ibk3.oli2 +0 -0
  184. package/sample-store/gen-1/predicate-9.ibk3.oli2.merkle +0 -1
  185. package/sample-store/gen-1/predicate-9.ibk3.sri2 +0 -0
  186. package/sample-store/gen-1/predicate-9.ibk3.sri2.merkle +0 -3
  187. package/sample-store/gen-1/predicate-9.ibk3.tli1 +0 -0
  188. package/sample-store/gen-1/predicate-9.ibk3.tli1.merkle +0 -2
  189. package/select.d.ts +0 -116
  190. package/select.js +0 -492
  191. package/version.json +0 -102
  192. package/wasm.d.ts +0 -130
  193. package/wasm.js +0 -158
package/index.js CHANGED
@@ -1,237 +1,7 @@
1
- // factoidal — formally-verified SPARQL 1.1 + RDF 1.1 for Node.
2
- //
3
- // CommonJS entry point (js_of_ocaml engine). Public API:
4
- //
5
- // parse(text, {format, baseIRI}) -> Promise<Dataset>
6
- // query(data, sparql, {entail}) -> Promise<Bindings[] | boolean | Dataset>
7
- // queryHdt(hdtBytes, sparql) -> Promise<Bindings[] | boolean>
8
- // (read-only HDT artifact, CLI-only,
9
- // no npm-entry bundle needed)
10
- // update(data, updateText) -> Promise<Dataset>
11
- // serialize(data, {format}) -> Promise<string>
12
- // canonicalize(data, {format}) -> Promise<string> (RDFC-1.0)
13
- // graphs(dataset) -> Array<[iri, Dataset]> (named graphs)
14
- // canonicalHash(datasetOrGraph) -> Promise<string> (RDFC-1.0, one graph)
15
- // shaclValidate(data, shapes) -> Promise<{conforms, report: Dataset}>
16
- // shexValidate(data, schema, focus, shape) -> Promise<boolean|null>
17
- // owlClosure(data, mode) -> Promise<Dataset> ('RDFS'|'OWL-RL')
18
- // rmlMap(mapping, sourceData, kind) -> Promise<Dataset> (kind: 'json'|'csv')
19
- // csvwToRdf(csvText, metadataJson, options) -> Promise<Dataset> (CSVW csv2rdf)
20
- // jsonldToRdf(jsonldText, options) -> Promise<Dataset>
21
- // rifEval(data, rifRulesXml) -> Promise<Dataset> (RIF Core saturation)
22
- // openCottas(bytes) -> Promise<string> (handle; bytes is
23
- // hex|Uint8Array|ArrayBuffer of a
24
- // whole .cottas artifact)
25
- // queryCottas(handle, sparql) -> Promise<Bindings[] | boolean | Dataset>
26
- // (in-memory COTTAS bytes store --
27
- // rows decode lazily, no heap Dataset)
28
- // closeCottas(handle) -> Promise<void>
29
- // toCottas(data) -> Promise<Uint8Array> (native COTTAS
30
- // writer; round-trips into openCottas)
31
- // dataFactory -> RDF/JS DataFactory
32
- // Dataset -> RDF/JS DatasetCore class
33
- //
34
- // shaclValidate/shexValidate/owlClosure/rmlMap/csvwToRdf/jsonldToRdf/rifEval/
35
- // openCottas/queryCottas/closeCottas/toCottas need the npm-entry ABI bundle
36
- // (same gate as update()/canonicalize()); see capabilities() to probe for it.
37
- // See docs/designissues/2026-07-06-inmemory-bytes-store.md for the
38
- // openCottas/queryCottas/toCottas design and its documented divergences
39
- // from parse()/query() (no entailment, no write overlay, read-only).
40
- //
41
- // Bindings are Maps of variable name -> RDF/JS Term. See index.d.ts
42
- // for the full types and README.md for examples.
43
- //
44
- // The legacy single-shot API from 0.1.0-alpha scaffolding is kept as
45
- // queryRaw(dataString, queryString, {dataFormat, entail, output}) —
46
- // it returns parsed SPARQL Results JSON (or a raw string for
47
- // non-JSON output formats).
48
- //
49
- // For the wasm engine with the same API, require('factoidal/wasm').
1
+ // @factoidal/core for require(). The ES module index.mjs is the source;
2
+ // Node 22.12 and later load it through require(), so CommonJS and ES module
3
+ // callers share one module instance (one engine, one `Dataset` class).
50
4
 
51
5
  'use strict';
52
6
 
53
- const fs = require('node:fs');
54
- const path = require('node:path');
55
-
56
- const engine = require('./lib/engine-js.js');
57
- const { buildApi } = require('./lib/api.js');
58
- const rdfjs = require('./rdfjs.js');
59
-
60
- const pkg = require('./package.json');
61
- const version = pkg.version;
62
-
63
- // ---------------------------------------------------------------------
64
- // npm-entry ABI loader. The entry bundle (built from
65
- // bin/npm-entry/entry_jsoo.ml) registers `factoidalNpmEntry` on
66
- // module.exports (Node) / globalThis (browser). Optional — everything
67
- // the CLI bundle can do works without it.
68
- // ---------------------------------------------------------------------
69
-
70
- function entryCandidates() {
71
- const c = [];
72
- if (process.env.FACTOIDAL_NPM_ENTRY) c.push(process.env.FACTOIDAL_NPM_ENTRY);
73
- c.push(path.join(__dirname, 'factoidal-npm-entry.js'));
74
- c.push(path.resolve(
75
- __dirname, '..', '..', 'docs', 'fstar-extracted', 'factoidal-npm-entry.js'));
76
- return c;
77
- }
78
-
79
- function loadEntry() {
80
- for (const p of entryCandidates()) {
81
- if (!p || !fs.existsSync(p)) continue;
82
- const mod = require(p);
83
- const abi = (mod && mod.factoidalNpmEntry) ||
84
- (globalThis.factoidalNpmEntry);
85
- if (abi && typeof abi.queryDataset === 'function') return abi;
86
- }
87
- return null;
88
- }
89
-
90
- const api = buildApi({
91
- engineName: 'js',
92
- runCli: engine.runCli,
93
- loadEntry,
94
- // VC crypto init hook: the typed vc* wrappers auto-await this once,
95
- // on the first VC call, so a Node caller never has to remember the
96
- // HACL* wasm init step. initHacl() is idempotent + memoized.
97
- initCrypto: () => require('./hacl-init.js').initHacl(),
98
- });
99
-
100
- // ---------------------------------------------------------------------
101
- // Legacy raw API (pre-RDF/JS scaffolding surface, kept for the smoke
102
- // tests and for callers that want the CLI's other output formats).
103
- // ---------------------------------------------------------------------
104
-
105
- const OUTPUT_FORMATS = new Set(['json', 'csv', 'tsv', 'xml', 'table', 'ntriples']);
106
- const ENTAIL_VALUES = new Set(['none', 'RDFS', 'OWL-RL']);
107
- const DATA_FORMAT_EXT = {
108
- turtle: 'ttl', ttl: 'ttl', ntriples: 'nt', nt: 'nt', nquads: 'nq',
109
- nq: 'nq', trig: 'trig', rdfxml: 'rdf', 'rdf-xml': 'rdf', rdf: 'rdf',
110
- };
111
-
112
- function queryRaw(dataString, queryString, options) {
113
- return Promise.resolve().then(() => {
114
- if (typeof dataString !== 'string') {
115
- throw new TypeError('queryRaw: dataString must be a string');
116
- }
117
- if (typeof queryString !== 'string') {
118
- throw new TypeError('queryRaw: queryString must be a string');
119
- }
120
- const opts = options || {};
121
- const dataFormat = String(opts.dataFormat || 'turtle').toLowerCase();
122
- const entail = opts.entail || 'none';
123
- const output = opts.output || 'json';
124
- if (!(dataFormat in DATA_FORMAT_EXT)) {
125
- throw new TypeError(`queryRaw: unknown dataFormat '${opts.dataFormat}'`);
126
- }
127
- if (!ENTAIL_VALUES.has(entail)) {
128
- throw new TypeError(
129
- `queryRaw: entail must be one of ${[...ENTAIL_VALUES].join(', ')}`);
130
- }
131
- if (!OUTPUT_FORMATS.has(output)) {
132
- throw new TypeError(
133
- `queryRaw: output must be one of ${[...OUTPUT_FORMATS].join(', ')}`);
134
- }
135
-
136
- const name = `/static/data.${DATA_FORMAT_EXT[dataFormat]}`;
137
- const args = ['-d', name, '-e', queryString, '-o', output];
138
- if (entail !== 'none') args.push('--entail', entail);
139
-
140
- const res = engine.runCli(args, [{ name, content: dataString }]);
141
- if (res.exitCode !== 0) {
142
- const msg = (res.stderr || res.stdout ||
143
- `factoidal exited with code ${res.exitCode}`).trim();
144
- const err = new Error('SPARQL query failed: ' + msg);
145
- err.exitCode = res.exitCode;
146
- err.stderr = res.stderr;
147
- err.stdout = res.stdout;
148
- throw err;
149
- }
150
- if (output !== 'json') return res.stdout;
151
-
152
- const first = res.stdout.indexOf('{');
153
- const last = res.stdout.lastIndexOf('}');
154
- if (first < 0 || last < first) {
155
- const err = new Error(
156
- 'factoidal did not produce JSON on stdout. Raw output: ' + res.stdout);
157
- err.stdout = res.stdout;
158
- err.stderr = res.stderr;
159
- throw err;
160
- }
161
- return JSON.parse(res.stdout.slice(first, last + 1));
162
- });
163
- }
164
-
165
- module.exports = {
166
- // Public typed API
167
- parse: api.parse,
168
- query: api.query,
169
- queryHdt: api.queryHdt,
170
- registerExtensionFunction: api.registerExtensionFunction,
171
- unregisterExtensionFunction: api.unregisterExtensionFunction,
172
- clearExtensionFunctions: api.clearExtensionFunctions,
173
- registerServiceEndpoint: api.registerServiceEndpoint,
174
- clearServiceEndpoints: api.clearServiceEndpoints,
175
- update: api.update,
176
- serialize: api.serialize,
177
- canonicalize: api.canonicalize,
178
- graphs: api.graphs,
179
- canonicalHash: api.canonicalHash,
180
- shaclValidate: api.shaclValidate,
181
- shexValidate: api.shexValidate,
182
- owlClosure: api.owlClosure,
183
- coreRdfsClosure: api.coreRdfsClosure,
184
- rdfsPlusClosure: api.rdfsPlusClosure,
185
- coreRdfsCheck: api.coreRdfsCheck,
186
- rhoDfClosure: api.rhoDfClosure,
187
- rhoDfFragmentCheck: api.rhoDfFragmentCheck,
188
- tableauMaterialise: api.tableauMaterialise,
189
- tableauDlInconsistent: api.tableauDlInconsistent,
190
- owlIsConsistent: api.owlIsConsistent,
191
- owlEntails: api.owlEntails,
192
- rmlMap: api.rmlMap,
193
- csvwToRdf: api.csvwToRdf,
194
- jsonldToRdf: api.jsonldToRdf,
195
- jsonldFromRdf: api.jsonldFromRdf,
196
- didKeyResolve: api.didKeyResolve,
197
- xmlWellformed: api.xmlWellformed,
198
- xpathEval: api.xpathEval,
199
- rifEval: api.rifEval,
200
- xsltTransform: api.xsltTransform,
201
- mathmlEval: api.mathmlEval,
202
- xformsRecalc: api.xformsRecalc,
203
- jsonSchemaValidate: api.jsonSchemaValidate,
204
- schematronValidate: api.schematronValidate,
205
- toanSummation: api.toanSummation,
206
- toanProduct: api.toanProduct,
207
- toanSimplify: api.toanSimplify,
208
- toanDiff: api.toanDiff,
209
- toanSubst: api.toanSubst,
210
- matrixDeterminant: api.matrixDeterminant,
211
- matrixScalarProduct: api.matrixScalarProduct,
212
- matrixVectorProduct: api.matrixVectorProduct,
213
- matrixOuterProduct: api.matrixOuterProduct,
214
- sigmoidPoints: api.sigmoidPoints,
215
- sigmoidFormulaMathml: api.sigmoidFormulaMathml,
216
- vcSha256Hex: api.vcSha256Hex,
217
- vcEd25519SecretToPublic: api.vcEd25519SecretToPublic,
218
- vcEd25519Sign: api.vcEd25519Sign,
219
- vcEd25519Verify: api.vcEd25519Verify,
220
- vcEddsaCreateFromCanonical: api.vcEddsaCreateFromCanonical,
221
- vcEddsaVerifyFromCanonical: api.vcEddsaVerifyFromCanonical,
222
- vcCheckCredential: api.vcCheckCredential,
223
- vcCheckCredentialSubject: api.vcCheckCredentialSubject,
224
- vcCheckNoDataLoss: api.vcCheckNoDataLoss,
225
- vcCheckRelatedResourceDigests: api.vcCheckRelatedResourceDigests,
226
- openCottas: api.openCottas,
227
- queryCottas: api.queryCottas,
228
- closeCottas: api.closeCottas,
229
- toCottas: api.toCottas,
230
- capabilities: api.capabilities,
231
- Dataset: rdfjs.Dataset,
232
- dataFactory: rdfjs.dataFactory,
233
- // Legacy raw surface
234
- queryRaw,
235
- // Metadata
236
- version,
237
- };
7
+ module.exports = require('./index.mjs');
package/index.mjs CHANGED
@@ -1,85 +1,177 @@
1
- // ESM entry point. Re-exports the CJS implementation so we have one
2
- // source of truth for the Node-side driver. Browsers should import
3
- // `./browser.js` via the `"browser"` export condition instead.
1
+ // @factoidal/core — the Node entry (ES module). One engine: the Lean 4
2
+ // library L4Factoidal (formal/lean4) compiled to WebAssembly.
4
3
  //
5
- // import { parse, query, canonicalize, dataFactory } from '@factoidal/core';
6
- // const ds = await parse('@prefix : <http://ex/> . :a :p :b .');
7
- // const rows = await query(ds, 'SELECT * WHERE { ?s ?p ?o }');
8
-
9
- import cjs from './index.js';
10
-
11
- export const parse = cjs.parse;
12
- export const query = cjs.query;
13
- export const queryHdt = cjs.queryHdt;
14
- export const registerExtensionFunction = cjs.registerExtensionFunction;
15
- export const unregisterExtensionFunction = cjs.unregisterExtensionFunction;
16
- export const clearExtensionFunctions = cjs.clearExtensionFunctions;
17
- export const registerServiceEndpoint = cjs.registerServiceEndpoint;
18
- export const clearServiceEndpoints = cjs.clearServiceEndpoints;
19
- export const update = cjs.update;
20
- export const serialize = cjs.serialize;
21
- export const canonicalize = cjs.canonicalize;
22
- export const graphs = cjs.graphs;
23
- export const canonicalHash = cjs.canonicalHash;
24
- export const capabilities = cjs.capabilities;
25
- export const Dataset = cjs.Dataset;
26
- export const dataFactory = cjs.dataFactory;
27
- export const queryRaw = cjs.queryRaw;
28
- export const version = cjs.version;
29
-
30
- // Validation / inference / mapping engines (need the npm-entry bundle).
31
- export const shaclValidate = cjs.shaclValidate;
32
- export const shexValidate = cjs.shexValidate;
33
- export const owlClosure = cjs.owlClosure;
34
- export const coreRdfsClosure = cjs.coreRdfsClosure;
35
- export const rdfsPlusClosure = cjs.rdfsPlusClosure;
36
- export const coreRdfsCheck = cjs.coreRdfsCheck;
37
- export const rhoDfClosure = cjs.rhoDfClosure;
38
- export const rhoDfFragmentCheck = cjs.rhoDfFragmentCheck;
39
- export const tableauMaterialise = cjs.tableauMaterialise;
40
- export const tableauDlInconsistent = cjs.tableauDlInconsistent;
41
- export const owlIsConsistent = cjs.owlIsConsistent;
42
- export const owlEntails = cjs.owlEntails;
43
- export const rmlMap = cjs.rmlMap;
44
- export const csvwToRdf = cjs.csvwToRdf;
45
- export const jsonldToRdf = cjs.jsonldToRdf;
46
- export const jsonldFromRdf = cjs.jsonldFromRdf;
47
- export const didKeyResolve = cjs.didKeyResolve;
48
- export const xmlWellformed = cjs.xmlWellformed;
49
- export const xpathEval = cjs.xpathEval;
50
- export const rifEval = cjs.rifEval;
51
-
52
- // In-memory COTTAS/Parquet bytes store (need the npm-entry bundle).
53
- export const openCottas = cjs.openCottas;
54
- export const queryCottas = cjs.queryCottas;
55
- export const closeCottas = cjs.closeCottas;
56
- export const toCottas = cjs.toCottas;
57
-
58
- // Typed engine functions (#74 npm FP surface).
59
- export const xsltTransform = cjs.xsltTransform;
60
- export const mathmlEval = cjs.mathmlEval;
61
- export const xformsRecalc = cjs.xformsRecalc;
62
- export const jsonSchemaValidate = cjs.jsonSchemaValidate;
63
- export const schematronValidate = cjs.schematronValidate;
64
- export const toanSummation = cjs.toanSummation;
65
- export const toanProduct = cjs.toanProduct;
66
- export const toanSimplify = cjs.toanSimplify;
67
- export const toanDiff = cjs.toanDiff;
68
- export const toanSubst = cjs.toanSubst;
69
- export const matrixDeterminant = cjs.matrixDeterminant;
70
- export const matrixScalarProduct = cjs.matrixScalarProduct;
71
- export const matrixVectorProduct = cjs.matrixVectorProduct;
72
- export const matrixOuterProduct = cjs.matrixOuterProduct;
73
- export const sigmoidPoints = cjs.sigmoidPoints;
74
- export const sigmoidFormulaMathml = cjs.sigmoidFormulaMathml;
75
-
76
- // VC Data Integrity crypto (eddsa-rdfc-2022, HACL* wasm backend). The
77
- // typed wrappers auto-await initHacl() on first call (see index.js).
78
- export const vcSha256Hex = cjs.vcSha256Hex;
79
- export const vcEd25519SecretToPublic = cjs.vcEd25519SecretToPublic;
80
- export const vcEd25519Sign = cjs.vcEd25519Sign;
81
- export const vcEd25519Verify = cjs.vcEd25519Verify;
82
- export const vcEddsaCreateFromCanonical = cjs.vcEddsaCreateFromCanonical;
83
- export const vcEddsaVerifyFromCanonical = cjs.vcEddsaVerifyFromCanonical;
84
-
85
- export default cjs;
4
+ // import { parse, query } from '@factoidal/core';
5
+ // const ds = await parse('@prefix : <http://ex/> . :a :p :b .');
6
+ // const rows = await query(ds, 'SELECT * WHERE { ?s ?p ?o }');
7
+ //
8
+ // The engine loads on the first call. Its three files sit in this
9
+ // package's l4-assets/ (l4factoidal.js, l4factoidal.mjs,
10
+ // l4factoidal.wasm); $FACTOIDAL_L4_ASSETS names another directory with
11
+ // the same three files, and a repository checkout falls back to
12
+ // docs/web/hub/assets/l4/ (bin/engine.mjs resolves them, for this module
13
+ // and for the `factoidal` command, so both share one engine instance).
14
+ //
15
+ // index.js gives the same module to require(). browser.js is the browser
16
+ // entry; api.mjs takes an engine the caller loaded itself.
17
+ //
18
+ // Types: index.d.ts. Every function is in lib/api.mjs.
19
+
20
+ import { readFileSync } from 'node:fs';
21
+ import { join } from 'node:path';
22
+ import { buildApi } from './lib/api.mjs';
23
+ import { entryFromEngine } from './lib/lean-entry.mjs';
24
+
25
+ /**
26
+ * The loaded Lean engine handle: `call(op, args)`, `callBlob`,
27
+ * `callBlobIO`, `version()`, over the dispatch ABI of
28
+ * formal/lean4/Wasm/Dispatch.lean. For the ops this package does not wrap
29
+ * (the `ops` op lists every name). Loaded once per process.
30
+ * @returns {Promise<object>}
31
+ */
32
+ export async function loadEngine() {
33
+ // A dynamic import: bin/engine.mjs reads files through store-host/, which
34
+ // picks its Node or Deno implementation with a top-level await, and a
35
+ // module that require() loads may not have one in its static graph.
36
+ const mod = await import('./bin/engine.mjs');
37
+ return mod.loadEngine();
38
+ }
39
+
40
+ const api = buildApi({
41
+ engineName: 'lean4-wasm',
42
+ loadEntry: async () => entryFromEngine(await loadEngine()),
43
+ storeReaderFor: (root) => (path) => readFileSync(join(root, path)),
44
+ });
45
+
46
+ // RDF and SPARQL
47
+ export const parse = api.parse;
48
+ export const query = api.query;
49
+ export const update = api.update;
50
+ export const serialize = api.serialize;
51
+ export const canonicalize = api.canonicalize;
52
+ export const graphs = api.graphs;
53
+ export const canonicalHash = api.canonicalHash;
54
+ export const openDataset = api.openDataset;
55
+ export const closure = api.closure;
56
+ export const formats = api.formats;
57
+ export const queryRaw = api.queryRaw;
58
+ export const queryHdt = api.queryHdt;
59
+ export const registerExtensionFunction = api.registerExtensionFunction;
60
+ export const unregisterExtensionFunction = api.unregisterExtensionFunction;
61
+ export const clearExtensionFunctions = api.clearExtensionFunctions;
62
+ export const registerServiceEndpoint = api.registerServiceEndpoint;
63
+ export const clearServiceEndpoints = api.clearServiceEndpoints;
64
+
65
+ // The persisted store
66
+ export const openStore = api.openStore;
67
+ export const queryStore = api.queryStore;
68
+ export const listStores = api.listStores;
69
+
70
+ // The durable update log (hub post 18)
71
+ export const deltaLogOpen = api.deltaLogOpen;
72
+ export const deltaLogAppend = api.deltaLogAppend;
73
+ export const deltaLogReadAllHex = api.deltaLogReadAllHex;
74
+ export const deltaLogMerge = api.deltaLogMerge;
75
+ export const deltaLogInspect = api.deltaLogInspect;
76
+ export const deltaLogDestroy = api.deltaLogDestroy;
77
+ export const _deltaLogCorruptLastForTest = api._deltaLogCorruptLastForTest;
78
+
79
+ // Validation and reasoning
80
+ export const shaclValidate = api.shaclValidate;
81
+ export const shexValidate = api.shexValidate;
82
+ export const owlClosure = api.owlClosure;
83
+ export const coreRdfsClosure = api.coreRdfsClosure;
84
+ export const coreRdfsCheck = api.coreRdfsCheck;
85
+ export const rdfsPlusClosure = api.rdfsPlusClosure;
86
+ export const rhoDfClosure = api.rhoDfClosure;
87
+ export const rhoDfFragmentCheck = api.rhoDfFragmentCheck;
88
+ export const tableauMaterialise = api.tableauMaterialise;
89
+ export const tableauDlInconsistent = api.tableauDlInconsistent;
90
+ export const owlIsConsistent = api.owlIsConsistent;
91
+ export const owlEntails = api.owlEntails;
92
+ export const rifEval = api.rifEval;
93
+
94
+ // Mappings and other formats
95
+ export const rmlMap = api.rmlMap;
96
+ export const csvwToRdf = api.csvwToRdf;
97
+ export const jsonldToRdf = api.jsonldToRdf;
98
+ export const jsonldFromRdf = api.jsonldFromRdf;
99
+ export const xmlWellformed = api.xmlWellformed;
100
+ export const xpathEval = api.xpathEval;
101
+ export const xsltTransform = api.xsltTransform;
102
+ export const schematronValidate = api.schematronValidate;
103
+ export const jsonSchemaValidate = api.jsonSchemaValidate;
104
+ export const mathmlEval = api.mathmlEval;
105
+ export const xformsRecalc = api.xformsRecalc;
106
+
107
+ // Common Logic
108
+ export const clParse = api.clParse;
109
+ export const clSerialize = api.clSerialize;
110
+ export const clAlphaNorm = api.clAlphaNorm;
111
+ export const clNormalize = api.clNormalize;
112
+
113
+ // Maths
114
+ export const toanSummation = api.toanSummation;
115
+ export const toanProduct = api.toanProduct;
116
+ export const toanSimplify = api.toanSimplify;
117
+ export const toanDiff = api.toanDiff;
118
+ export const toanSubst = api.toanSubst;
119
+
120
+ // Verifiable Credentials and DID
121
+ export const vcSha256Hex = api.vcSha256Hex;
122
+ export const vcEd25519SecretToPublic = api.vcEd25519SecretToPublic;
123
+ export const vcEd25519Sign = api.vcEd25519Sign;
124
+ export const vcEd25519Verify = api.vcEd25519Verify;
125
+ export const vcEddsaCreateFromCanonical = api.vcEddsaCreateFromCanonical;
126
+ export const vcEddsaVerifyFromCanonical = api.vcEddsaVerifyFromCanonical;
127
+ export const vcCheckCredential = api.vcCheckCredential;
128
+ export const vcCheckCredentialSubject = api.vcCheckCredentialSubject;
129
+ export const vcCheckNoDataLoss = api.vcCheckNoDataLoss;
130
+ export const vcCheckRelatedResourceDigests = api.vcCheckRelatedResourceDigests;
131
+ export const didKeyResolve = api.didKeyResolve;
132
+
133
+ // Types, probes and metadata
134
+ export const capabilities = api.capabilities;
135
+ export const Dataset = api.Dataset;
136
+ export const DatasetHandle = api.DatasetHandle;
137
+ export const Store = api.Store;
138
+ export const ParseError = api.ParseError;
139
+ export const dataFactory = api.dataFactory;
140
+ export const version = api.version;
141
+ export const engine = api.engine;
142
+
143
+ export default api;
144
+
145
+ // Pure functions over engine ops added in 0.10.0 (lib/pure.mjs).
146
+ import { buildPure } from './lib/pure.mjs';
147
+ const pure = buildPure(loadEngine);
148
+ export const aeadSeal = pure.aeadSeal;
149
+ export const aeadOpen = pure.aeadOpen;
150
+ export const hpkeSeal = pure.hpkeSeal;
151
+ export const hpkeOpen = pure.hpkeOpen;
152
+ export const proofCheck = pure.proofCheck;
153
+ export const proofInspect = pure.proofInspect;
154
+ export const canonicalizeNQuads = pure.canonicalizeNQuads;
155
+ export const normalizeNQuads = pure.normalizeNQuads;
156
+
157
+ /**
158
+ * Serve an activated store (a collection root that holds CURRENT) over the
159
+ * SPARQL 1.1 Protocol, the Graph Store Protocol and the Service
160
+ * Description: the same server as `factoidal serve STORE`. Node only.
161
+ * With `{tdb2: true}`, `root` is an Apache Jena TDB2 database directory,
162
+ * read in place and served read only (updates answer 501;
163
+ * https://github.com/danbri/factoidal/issues/834).
164
+ * @param {string} root
165
+ * @param {{port?: number, host?: string, queryPath?: string, gspPath?: string,
166
+ * tdb2?: boolean}} [options] port 0 (default) picks one
167
+ * @returns {Promise<{url: string, port: number, close: () => Promise<void>}>}
168
+ */
169
+ export async function serveStore(root, options = {}) {
170
+ const { listen } = await import('./bin/serve.mjs');
171
+ const s = await listen(root, { ...options, engine: await loadEngine() });
172
+ return { url: `${s.origin}${options.queryPath ?? "/sparql"}`, port: s.port, close: () => s.close() };
173
+ }
174
+
175
+ // A small store packed on demand from triples held in sample-store.mjs (no
176
+ // data file ships; owner, 2026-10-20). Node only.
177
+ export { sampleStorePath, sampleStoreFacts } from './sample-store.mjs';
@@ -37,7 +37,7 @@
37
37
  // bytes change.
38
38
 
39
39
  // Stamped by formal/lean4/Wasm/build-wasm.sh step 9 -- do not hand-edit.
40
- const WASM_VERSION = "a7720d5d5630";
40
+ const WASM_VERSION = "2347d124e551";
41
41
 
42
42
  import createModule from './l4factoidal.mjs';
43
43
 
@@ -51,13 +51,28 @@ let modulePromise = null;
51
51
  // staleness this fixes can actually happen.
52
52
  const isNodeLike = !!(globalThis.process && globalThis.process.versions && globalThis.process.versions.node);
53
53
 
54
+ /** The content-hash version of the wasm this loader was built with. */
55
+ export const wasmVersion = WASM_VERSION;
56
+
54
57
  /**
55
58
  * Instantiate the Lean engine (once per module instance; repeated calls
56
- * return the same promise). Resolves to the API object.
59
+ * return the same promise, and options after the first call are ignored).
60
+ * Resolves to the API object.
61
+ *
62
+ * `options.instantiateWasm(imports)` replaces the glue's own fetch and
63
+ * compile: it receives the import object and answers a Promise of
64
+ * `{instance, module}`, the value of `WebAssembly.instantiateStreaming`.
65
+ * A page that serves the wasm from its own URL uses it:
66
+ *
67
+ * loadL4({ instantiateWasm: (imports) =>
68
+ * WebAssembly.instantiateStreaming(fetch(url), imports) });
69
+ *
70
+ * A rejection of that Promise rejects loadL4().
57
71
  */
58
- export function loadL4() {
72
+ export function loadL4(options) {
59
73
  if (modulePromise) return modulePromise;
60
74
  modulePromise = (async () => {
75
+ const opts = options || {};
61
76
  const moduleArg = isNodeLike ? {} : {
62
77
  // Called by the Emscripten glue only to resolve the sibling
63
78
  // .wasm (see l4factoidal.mjs's findWasmBinary); appending the
@@ -69,7 +84,22 @@ export function loadL4() {
69
84
  : scriptDirectory + path;
70
85
  },
71
86
  };
72
- const Module = await createModule(moduleArg);
87
+ // The glue calls Module.instantiateWasm(imports, receive) and waits for
88
+ // receive(); it has no failure path, so a failure is raced in here.
89
+ let instantiateFailed = null;
90
+ if (typeof opts.instantiateWasm === 'function') {
91
+ let fail;
92
+ instantiateFailed = new Promise((_resolve, reject) => { fail = reject; });
93
+ moduleArg.instantiateWasm = (imports, receive) => {
94
+ Promise.resolve()
95
+ .then(() => opts.instantiateWasm(imports))
96
+ .then((r) => receive(r.instance, r.module), fail);
97
+ return {};
98
+ };
99
+ }
100
+ const Module = instantiateFailed
101
+ ? await Promise.race([createModule(moduleArg), instantiateFailed])
102
+ : await createModule(moduleArg);
73
103
 
74
104
  const cVersion = Module.cwrap('l4_version_c', 'number', []);
75
105
  const cFree = Module.cwrap('l4_free_result', null, ['number']);
@@ -87,6 +117,16 @@ export function loadL4() {
87
117
 
88
118
  const asJson = (v) => (typeof v === 'string' ? v : JSON.stringify(v));
89
119
 
120
+ /**
121
+ * The Error thrown for an {"ok":false,...} envelope. The message is
122
+ * unchanged (`l4factoidal: <error>`); the WHOLE envelope rides along as
123
+ * `.envelope`, so a caller can read the members beyond `error` that some
124
+ * refusals carry (a parse failure's `line`, `column`, `offset` and
125
+ * `format`, https://github.com/danbri/factoidal/issues/685).
126
+ */
127
+ const refusal = (envelope) =>
128
+ Object.assign(new Error(`l4factoidal: ${envelope.error}`), { envelope });
129
+
90
130
  // Emscripten's cwrap `string` converter uses the WebAssembly stack.
91
131
  // Multi-megabyte RDF/block requests can therefore overflow STACK_SIZE
92
132
  // before Lean sees them. Allocate input UTF-8 on the wasm heap instead;
@@ -146,7 +186,7 @@ export function loadL4() {
146
186
  const resultPtr = callWithHeapStrings(Module._l4_call_c,
147
187
  [op, JSON.stringify(args)]);
148
188
  const parsed = JSON.parse(take(resultPtr));
149
- if (parsed.ok === false) throw new Error(`l4factoidal: ${parsed.error}`);
189
+ if (parsed.ok === false) throw refusal(parsed);
150
190
  return parsed;
151
191
  },
152
192
 
@@ -180,7 +220,7 @@ export function loadL4() {
180
220
  (opPtr, argsPtr) => Module._l4_call_blob_c(opPtr, argsPtr, blobPtr, bytes.length),
181
221
  [op, JSON.stringify(args)]);
182
222
  const parsed = JSON.parse(take(resultPtr));
183
- if (parsed.ok === false) throw new Error(`l4factoidal: ${parsed.error}`);
223
+ if (parsed.ok === false) throw refusal(parsed);
184
224
  return parsed;
185
225
  } finally {
186
226
  if (blobPtr) Module._free(blobPtr);
@@ -233,7 +273,7 @@ export function loadL4() {
233
273
  outPtr = Module.getValue(outCell, 'i32') >>> 0;
234
274
  const outLen = Module.getValue(outCell + 4, 'i32') >>> 0;
235
275
  const envelope = JSON.parse(take(resultPtr));
236
- if (envelope.ok === false) throw new Error(`l4factoidal: ${envelope.error}`);
276
+ if (envelope.ok === false) throw refusal(envelope);
237
277
  // slice() copies; HEAPU8 is replaced wholesale when the
238
278
  // module's memory grows, so a view would not survive.
239
279
  const region = outPtr !== 0 && outLen > 0