@factoidal/core 0.19.0 → 0.20.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 +16 -0
- package/README.md +21 -13
- package/browser.d.ts +13 -0
- package/browser.js +14 -0
- package/index.d.ts +220 -20
- package/index.mjs +14 -0
- package/l4-assets/l4factoidal.js +1 -1
- package/l4-assets/l4factoidal.wasm +0 -0
- package/l4-assets/version.json +6 -6
- package/lib/api.mjs +251 -23
- package/lib/dataset.mjs +96 -12
- package/lib/lean-entry.mjs +30 -12
- package/lib/nodes.mjs +92 -14
- package/lib/sbm11-lws.mjs +4 -2
- package/lib/sbm11.mjs +16 -6
- package/lib/version.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.20.0 (2026-10-27)
|
|
6
|
+
|
|
7
|
+
- **Breaking:** in a checked pipeline (`node`, `pipe`, `run`), each node now puts a value of its output wire on the wire: text after a writer, the rows after SELECT, a boolean after ASK, the report after `shaclValidator`, `[canonical, sha256]` after `rdfcStage`, the result after `rdfsExplainGraphStage`. Before, such a node left its input Dataset on the wire, so a well-typed reader → writer → reader pipeline failed at run time. `run()` rejects a runner value that is not of the node's `wireOut`. `rdfcStage` as a node takes a Dataset only (https://github.com/danbri/factoidal-core/pull/155).
|
|
8
|
+
- `node()` keeps its own copy of its settings (frozen at every depth; a Dataset is cloned). A change to the caller's objects after `node()` no longer changes what runs while the evidence keeps the old `settingsDigest`. `run()` rejects a node whose settings changed through `node.params` (https://github.com/danbri/factoidal-core/pull/155).
|
|
9
|
+
- **Breaking:** `canonicalHash(dataset)` keeps graph names: it is the SHA-256 of the text `canonicalize()` answers. 0.17.0 to 0.19.0 dropped graph names, so datasets that differ only in graph names got one hash. New `asDefaultGraph(dataset)`; `canonicalHash(asDefaultGraph(g))` gives a graph's hash whatever its name (https://github.com/danbri/factoidal-core/pull/155).
|
|
10
|
+
- SBM11 stores opened with `openSbm11` (and the wasm ops `sbm11Open` / `sbm11Query`) are checked against their Merkle roots by default: the open admits each file's `.merkle` sidecar against `manifest.sbm11`, and every byte a query decodes comes from a 65,536-byte chunk checked by its Merkle proof. A changed data file, sidecar or Merkle reference in the manifest fails the open or the query with an error that names the file (before, a changed `dict.gdv1` was answered as data). `openSbm11(source, { verify: 'none' })` keeps the earlier length-only check; `store.verify` says which mode is in use. Measured cost: within run-to-run noise on stores of 1 to 6 MB (https://github.com/danbri/factoidal-core/pull/157).
|
|
11
|
+
- Parse is faster again after the IRI check of 0.19.0 (https://github.com/danbri/factoidal/issues/1057): the check tests bytes, and a repeated IRI is not checked again. Parse of 100,000 triples is now about 3% slower than 0.18.0 (it was 10% to 19%). The IRIs that are accepted and refused do not change (https://github.com/danbri/factoidal-core/pull/158).
|
|
12
|
+
- CID 1.0 (Controlled Identifiers, W3C Recommendation 2025-05-15): new Lean module `L4Factoidal/CID/` with the section 2 data model (one named error per MUST), Multikey and JsonWebKey material, the five verification relationships, Fragment Resolution, Retrieve Verification Method and the section 3.5 processing errors. The CID context is vendored. Authorization server, CID suite (lws10-authn-ssi-cid): the subject document is checked as a whole and the method is found by Retrieve Verification Method with `authentication`; `expires`/`revoked` need a time zone; `Accept` starts with `application/cid`. VC Data Integrity (Lean): `verificationMethod` can be a method in a controlled identifier document (not only an Ed25519 did:key), and it must be in the relationship that `proofPurpose` names. No npm functions yet (https://github.com/danbri/factoidal/issues/1100, https://github.com/danbri/factoidal-core/pull/161).
|
|
13
|
+
- `parse` takes the option `rdfstar` for JSON-LD, as the 0.18.0 changelog says: `parse(text, { format: 'jsonld', rdfstar: true })` reads `@triple`, `@reifies` and `@annotation` as RDF 1.2 triple terms and reifiers, as `jsonldToRdf` does. 0.18.0 and 0.19.0 refused the option with `option.unknown`. `rdfstar` with another format, or with `lenient`, is refused with `option.conflict` (https://github.com/danbri/factoidal/issues/1091, https://github.com/danbri/factoidal-core/pull/152).
|
|
14
|
+
- Docs: hub page "JSON-LD-star and JSON-LD 1.3" (`docs/web/hub/jsonld-star.md`), with live cells on 0.19.0; the hub pages load 0.19.0 (were 0.16.0).
|
|
15
|
+
- Value matching (https://github.com/danbri/factoidal/issues/1052): new `sameValue(a, b)` is SPARQL 1.1 `=` on two terms (sections 17.3, 17.4.1.7), decided by the engine (Lean `SPARQL/SameValue.lean`). It answers `true`, `false`, or `null` for incomparable (the type error of `=`). `Dataset.has`, `match` and `delete` take `{match: 'value'}`: a literal object then matches each object literal of the same value (`"1"^^xsd:int` finds `"01"^^xsd:integer` and `"1.0"^^xsd:decimal`), through an index of the literals by value. Term matching stays the default. New wasm op `sameValue`; `datasetMatch`, `datasetMatchCount` and `datasetDeleteQuadsJson` take an optional options argument.
|
|
16
|
+
- Syntax names (https://github.com/danbri/factoidal/issues/1053): new `syntaxFor(fileName)` and `syntaxFor({fileName, mediaType})` give the syntax of a document from the W3C registrations (Lean `RDF/MediaType.lean`), or `null`. Each row of `formats()` has `mediaTypes` and `extensions` from the same table (README format table: two new columns). New wasm op `syntaxFor`.
|
|
17
|
+
- IRIs, vocabularies, lists and containers (https://github.com/danbri/factoidal/issues/1051 items 4 to 6): new `splitIri(iri)` (namespace and the longest XML NCName suffix), `isNCName(text)`, `vocabularies()` (rdf, rdfs, xsd and owl with their terms; foaf, dcterms, dc and schema namespaces), `memberIri(n)` and `memberOrdinal(iri)` (`rdf:_n`). Dataset methods `listItems(head, graph?)` (refuses a list that is not well formed, with the reason), `containerItems(node, graph?)` and `addList(items, graph?)`. Lean `RDF/IriSplit.lean`, `RDF/VocabularyTable.lean`, `RDF/Collections.lean`. New wasm ops `splitIri`, `isNCName`, `vocabularies`, `memberIri`, `memberOrdinal`, `datasetListItems`, `datasetContainerItems`, `datasetAddList`. These need a wasm built from this source.
|
|
18
|
+
- Literal values (https://github.com/danbri/factoidal/issues/1051 items 1 to 3). New functions `literalValue(term)`, `isValidLiteral(term)`, `canonicalLiteral(term)` and `literalFromValue(value, {datatype?})`, synchronous after `ready()` (API.md "Literal values"). `literalValue` gives the XSD 1.1 lexical-to-value mapping of a literal for every XSD built-in the engine has (numeric types and the derived integer types with their bounds, boolean, the string types, date/time and `g*` types, durations, binary, lists) and for `rdf:langString`, `rdf:dirLangString`, `rdf:XMLLiteral`, `rdf:JSON`: `{datatype, recognized, valid, value?, canonical?}`, with the value as JSON-safe data (a number that a JavaScript number does not hold exactly is a decimal string). `valid: false` is an ill-typed literal; `recognized: false` is a datatype the engine does not have. `literalFromValue` maps a boolean, number, bigint, string or Date to a typed literal with one engine table (safe integer `xsd:integer`, other number `xsd:double`, bigint `xsd:integer`, Date `xsd:dateTime` in UTC), or to a named datatype (`{datatype: 'int'}`) when the value is in its value space, else a `FactoidalError` with the new code `literal.value`. New wasm ops `literalValue` and `literalFromValue` (Lean `L4Factoidal/RDF/LiteralValue.lean`, `Wasm/Ops/LiteralValue.lean`). An extension function may now answer a `Date` (an `xsd:dateTime`).
|
|
19
|
+
- The canonical form of an `xsd:float` or `xsd:double` value is now the XSD 1.1 Part 2 §3.3.4.2/§3.3.5.2 form (algorithm §E.1): the fewest significant digits that map back to the value. `"0.1"^^xsd:double` has the canonical form `1.0E-1`; before, it was the exact binary expansion `1.000000000000000055511151231257827021181583404541015625E-1`. It is the `canonical` member of `literalValue` and RML's canonical form of a double (RML-Core natural mapping). SPARQL casts do not change (`xsd:double("0.1")` is still `"0.1"^^xsd:double`). Theorems `double_canonical_roundTrip`, `float_canonical_roundTrip`, `integer_canonical_roundTrip` (`XSD/CanonicalTheorems.lean`).
|
|
20
|
+
|
|
5
21
|
## 0.19.0 (2026-10-27)
|
|
6
22
|
|
|
7
23
|
- Notice (owner decision, 2026-10-27): "EXPERIMENTAL UNREVIEWED CODE - USE WITH CARE - DO NOT CREATE PUBLIC SERVICES USING THIS WITHOUT CAREFUL INDEPENDENT EXPERT REVIEW." It is at the top of both READMEs and the hub, in the package description, in every `factoidal` help text, and on standard error when `serve`, `lws-serve`, `solid-serve`, `solid-client`, `lws-client`, `authz-serve`, `authz-keys`, `xmpp-serve` or `webdav-serve` starts.
|
package/README.md
CHANGED
|
@@ -38,10 +38,14 @@ every consumer accepts one, so a pipeline does not re-parse between steps.
|
|
|
38
38
|
An unknown option key throws. With no `format`, the format is inferred and
|
|
39
39
|
reported in `dataset.format`; an explicit `format` is never overridden.
|
|
40
40
|
RDF 1.2 input uses `turtle12`, `ntriples12`, `nquads12` or `trig12`.
|
|
41
|
+
RDF 1.2 in JSON-LD (JSON-LD-star: `@triple`, `@reifies`, `@annotation`,
|
|
42
|
+
`@direction`) needs the option `rdfstar`: `jsonldToRdf(text, { rdfstar: true })`
|
|
43
|
+
and `dataset.serialize({ format: 'jsonld', rdfstar: true })`.
|
|
41
44
|
|
|
42
45
|
## What it does
|
|
43
46
|
|
|
44
47
|
- Syntaxes: N-Triples, N-Quads, Turtle, TriG, RDF/XML, JSON-LD; RDF 1.1 and 1.2
|
|
48
|
+
(RDF 1.2 in JSON-LD through the JSON-LD-star draft, option `rdfstar`)
|
|
45
49
|
- SPARQL 1.1 and 1.2 query and update; GeoSPARQL functions, text search,
|
|
46
50
|
JavaScript extension functions, SERVICE
|
|
47
51
|
- Reasoning: RDFS, OWL 2 RL closure, restricted checked OWL consistency,
|
|
@@ -118,19 +122,19 @@ and marks those steps in the evidence. Details: API.md, "Stages as nodes" and
|
|
|
118
122
|
Formats (generated from `formats()`):
|
|
119
123
|
|
|
120
124
|
<!-- formats-table:start (generated by test/formats-table.test.mjs) -->
|
|
121
|
-
| format | read RDF 1.1 | read RDF 1.2 | write RDF 1.1 | write RDF 1.2 | engine |
|
|
122
|
-
|
|
123
|
-
| nquads | yes | yes | yes | yes | core |
|
|
124
|
-
| ntriples | yes | yes | yes | yes | core |
|
|
125
|
-
| turtle | yes | yes | yes | yes | core |
|
|
126
|
-
| trig | yes | yes | yes | yes | core |
|
|
127
|
-
| rdfxml | yes | no | yes | no | core |
|
|
128
|
-
| jsonld | yes | no | yes | no | full |
|
|
129
|
-
| rdfc | no | no | yes | no | core |
|
|
130
|
-
| sparql-results-json | no | no | yes | yes | core |
|
|
131
|
-
| sparql-results-xml | no | no | yes | yes | core |
|
|
132
|
-
| sparql-results-csv | no | no | yes | yes | core |
|
|
133
|
-
| sparql-results-tsv | no | no | yes | yes | core |
|
|
125
|
+
| format | read RDF 1.1 | read RDF 1.2 | write RDF 1.1 | write RDF 1.2 | engine | media type | extension |
|
|
126
|
+
|---|---|---|---|---|---|---|---|
|
|
127
|
+
| nquads | yes | yes | yes | yes | core | `application/n-quads` | `.nq` |
|
|
128
|
+
| ntriples | yes | yes | yes | yes | core | `application/n-triples` | `.nt` |
|
|
129
|
+
| turtle | yes | yes | yes | yes | core | `text/turtle` | `.ttl` |
|
|
130
|
+
| trig | yes | yes | yes | yes | core | `application/trig` | `.trig` |
|
|
131
|
+
| rdfxml | yes | no | yes | no | core | `application/rdf+xml` | `.rdf` |
|
|
132
|
+
| jsonld | yes | no | yes | no | full | `application/ld+json` | `.jsonld` |
|
|
133
|
+
| rdfc | no | no | yes | no | core | | |
|
|
134
|
+
| sparql-results-json | no | no | yes | yes | core | | |
|
|
135
|
+
| sparql-results-xml | no | no | yes | yes | core | | |
|
|
136
|
+
| sparql-results-csv | no | no | yes | yes | core | | |
|
|
137
|
+
| sparql-results-tsv | no | no | yes | yes | core | | |
|
|
134
138
|
<!-- formats-table:end -->
|
|
135
139
|
|
|
136
140
|
Missing writers (HDT, N3, RDFa): https://github.com/danbri/factoidal/issues/883.
|
|
@@ -160,6 +164,7 @@ Codes (generated from `engineTables().errorCodes`):
|
|
|
160
164
|
| `term.invalid-iri` | <https://www.w3.org/TR/rdf12-concepts/#section-IRIs> | A term that must be an IRI is not one. |
|
|
161
165
|
| `term.invalid-langtag` | <https://www.w3.org/TR/rdf12-concepts/#section-Graph-Literal> | A language tag is not well-formed (BCP 47). |
|
|
162
166
|
| `term.invalid` | <https://www.w3.org/TR/sparql11-results-json/#select-encode-terms> | A term or quad given as JSON is not an RDF term or quad. |
|
|
167
|
+
| `literal.value` | <https://www.w3.org/TR/xmlschema11-2/#value-space> | The value is not in the value space of the named datatype, or the datatype is not one the engine has. |
|
|
163
168
|
| `query.syntax` | <https://www.w3.org/TR/sparql11-query/#grammar> | The SPARQL query does not match the SPARQL grammar. |
|
|
164
169
|
| `query.failed` | <https://www.w3.org/TR/sparql11-query/#sparqlDefinition> | The SPARQL query parsed but its evaluation was refused. |
|
|
165
170
|
| `update.syntax` | <https://www.w3.org/TR/sparql11-update/#grammar> | The SPARQL update does not match the SPARQL Update grammar. |
|
|
@@ -239,6 +244,8 @@ and the [assurance record](https://github.com/danbri/factoidal-core/blob/main/do
|
|
|
239
244
|
| JSON-LD 1.1 toRdf, expand, flatten | 910 / 0 / 910 |
|
|
240
245
|
| JSON-LD 1.1 compact, fromRdf | 298 / 0 / 300 (2 not run) |
|
|
241
246
|
| JSON-LD 1.1 Framing | 29 / 63 / 92 |
|
|
247
|
+
| JSON-LD-star draft (RDF 1.2), option `rdfstar` | 168 / 1 / 171 (2 local override; 170 of 171 with them) [J] |
|
|
248
|
+
| RDF 1.2 eval tests written as JSON-LD-star and read back | 140 / 0 / 140 [J] |
|
|
242
249
|
| RDFC-1.0 | 86 / 0 / 86 |
|
|
243
250
|
| OWL 2 RL | 126 / 0 / 126 |
|
|
244
251
|
| OWL 2 DL type-inconsistency | 116 / 11 / 128 (1 other) |
|
|
@@ -262,6 +269,7 @@ and the [assurance record](https://github.com/danbri/factoidal-core/blob/main/do
|
|
|
262
269
|
[L] 2026-10-22, https://github.com/danbri/factoidal-core/blob/2b9d2e39af53be31ed92463b58d3e132e65c4fe4/docs/designissues/2026-10-21-lws-touchstone-run.md (with server options, 220 of 221 pass in at least one configuration)
|
|
263
270
|
[S] 2026-10-21, the current W3C manifest (29 active tests), https://github.com/danbri/factoidal-core/blob/2b9d2e39af53be31ed92463b58d3e132e65c4fe4/docs/claude-rules/current-state.md
|
|
264
271
|
[C] 2026-10-21, validation test308, https://github.com/danbri/factoidal/issues/700
|
|
272
|
+
[J] 2026-10-27, tests of https://github.com/json-ld/json-ld-star/pull/61; the fail is a defective fixture (fromRdf tst07), https://github.com/danbri/factoidal-core/blob/2a656d7bfb4af329d77669afb5e62eb00625bd15/docs/designissues/2026-10-26-jsonld-star.md
|
|
265
273
|
|
|
266
274
|
## Limits
|
|
267
275
|
|
package/browser.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type {
|
|
|
12
12
|
QueryOptions, SerializeOptions, StoreReader, OpenStoreOptions,
|
|
13
13
|
DeltaLogHandle, DeltaLogInspection,
|
|
14
14
|
Sbm11Reader, Sbm11Answer, Sbm11Store, Sbm11ReadEvidence, Sbm11Transport,
|
|
15
|
+
LiteralValueData, LiteralValueResult,
|
|
15
16
|
ExplainResult, StageInfo, EvidenceRecord, Wire, FactoidalNode, Pipeline, RunResult, RunOptions,
|
|
16
17
|
} from './index';
|
|
17
18
|
|
|
@@ -23,10 +24,22 @@ export {
|
|
|
23
24
|
canonicalize,
|
|
24
25
|
graphs,
|
|
25
26
|
canonicalHash,
|
|
27
|
+
asDefaultGraph,
|
|
26
28
|
isomorphic,
|
|
27
29
|
fromQuads,
|
|
30
|
+
literalValue,
|
|
31
|
+
isValidLiteral,
|
|
32
|
+
canonicalLiteral,
|
|
33
|
+
literalFromValue,
|
|
28
34
|
ready,
|
|
29
35
|
engineTables,
|
|
36
|
+
sameValue,
|
|
37
|
+
syntaxFor,
|
|
38
|
+
splitIri,
|
|
39
|
+
isNCName,
|
|
40
|
+
vocabularies,
|
|
41
|
+
memberIri,
|
|
42
|
+
memberOrdinal,
|
|
30
43
|
openDataset,
|
|
31
44
|
closure,
|
|
32
45
|
formats,
|
package/browser.js
CHANGED
|
@@ -83,10 +83,24 @@ export const serialize = api.serialize;
|
|
|
83
83
|
export const canonicalize = api.canonicalize;
|
|
84
84
|
export const graphs = api.graphs;
|
|
85
85
|
export const canonicalHash = api.canonicalHash;
|
|
86
|
+
export const asDefaultGraph = api.asDefaultGraph;
|
|
86
87
|
export const isomorphic = api.isomorphic;
|
|
87
88
|
export const fromQuads = api.fromQuads;
|
|
89
|
+
// Literal values (https://github.com/danbri/factoidal/issues/1051): synchronous
|
|
90
|
+
// after the engine is loaded.
|
|
91
|
+
export const literalValue = api.literalValue;
|
|
92
|
+
export const isValidLiteral = api.isValidLiteral;
|
|
93
|
+
export const canonicalLiteral = api.canonicalLiteral;
|
|
94
|
+
export const literalFromValue = api.literalFromValue;
|
|
88
95
|
export const ready = api.ready;
|
|
89
96
|
export const engineTables = api.engineTables;
|
|
97
|
+
export const sameValue = api.sameValue;
|
|
98
|
+
export const syntaxFor = api.syntaxFor;
|
|
99
|
+
export const splitIri = api.splitIri;
|
|
100
|
+
export const isNCName = api.isNCName;
|
|
101
|
+
export const vocabularies = api.vocabularies;
|
|
102
|
+
export const memberIri = api.memberIri;
|
|
103
|
+
export const memberOrdinal = api.memberOrdinal;
|
|
90
104
|
export const openDataset = api.openDataset;
|
|
91
105
|
export const closure = api.closure;
|
|
92
106
|
export const formats = api.formats;
|
package/index.d.ts
CHANGED
|
@@ -99,6 +99,7 @@ export type FactoidalErrorCode =
|
|
|
99
99
|
| 'term.invalid-iri'
|
|
100
100
|
| 'term.invalid-langtag'
|
|
101
101
|
| 'term.invalid'
|
|
102
|
+
| 'literal.value'
|
|
102
103
|
| 'query.syntax'
|
|
103
104
|
| 'query.failed'
|
|
104
105
|
| 'update.syntax'
|
|
@@ -236,6 +237,10 @@ export interface FormatCapability {
|
|
|
236
237
|
write12: boolean;
|
|
237
238
|
/** 'core' when both engines serve it; 'full' when only the full engine does. */
|
|
238
239
|
engine: 'core' | 'full';
|
|
240
|
+
/** The registered media types (W3C registration; empty for a row with none). syntaxFor() reads the same table. */
|
|
241
|
+
mediaTypes: string[];
|
|
242
|
+
/** The registered file extensions, with the leading dot ('.ttl'). */
|
|
243
|
+
extensions: string[];
|
|
239
244
|
}
|
|
240
245
|
|
|
241
246
|
/**
|
|
@@ -283,11 +288,31 @@ export class Dataset implements Iterable<Quad> {
|
|
|
283
288
|
toString(formatOrOptions?: WriteFormat | WriteOptions): string;
|
|
284
289
|
toNQuads(): string;
|
|
285
290
|
clone(): Dataset;
|
|
286
|
-
/**
|
|
287
|
-
|
|
291
|
+
/**
|
|
292
|
+
* RDF/JS DatasetCore (https://rdf.js.org/dataset-spec/); match and has use
|
|
293
|
+
* the engine indexes. `{match: 'value'}`: a literal object matches every
|
|
294
|
+
* object literal that is the same term or has the same value (sameValue());
|
|
295
|
+
* the other positions match by term.
|
|
296
|
+
*/
|
|
297
|
+
has(quad: Quad, options?: MatchOptions): boolean;
|
|
288
298
|
add(quad: Quad): this;
|
|
289
|
-
|
|
290
|
-
|
|
299
|
+
/** With `{match: 'value'}`: remove every quad of the same subject, predicate
|
|
300
|
+
* and graph whose object has the same value as the quad's literal object. */
|
|
301
|
+
delete(quad: Quad, options?: MatchOptions): this;
|
|
302
|
+
match(subject?: Term | null, predicate?: Term | null, object?: Term | null, graph?: Term | null,
|
|
303
|
+
options?: MatchOptions): Dataset;
|
|
304
|
+
/**
|
|
305
|
+
* The items of the RDF list (rdf:first/rdf:rest) at `head`, in order
|
|
306
|
+
* (https://github.com/danbri/factoidal/issues/1051 item 6). `rdf:nil` is
|
|
307
|
+
* the empty list. A list that is not well formed (a node with no or with two
|
|
308
|
+
* rdf:first or rdf:rest, or a cycle) is a FactoidalError, code `op.failed`.
|
|
309
|
+
* `graph`: omitted, null or the DefaultGraph for the default graph.
|
|
310
|
+
*/
|
|
311
|
+
listItems(head: Term, graph?: Term | null): Term[];
|
|
312
|
+
/** The members rdf:_1, rdf:_2, ... of `node`, sorted by n, and its kind (rdf:Bag, rdf:Seq, rdf:Alt) from its rdf:type. */
|
|
313
|
+
containerItems(node: Term, graph?: Term | null): { kind: NamedNode | null; items: Array<{ ordinal: number; term: Term }> };
|
|
314
|
+
/** Add a new RDF list of `items` on fresh blank nodes; answers its head (rdf:nil for no items). */
|
|
315
|
+
addList(items: Iterable<Term>, graph?: Term | null): Term;
|
|
291
316
|
toArray(): Quad[];
|
|
292
317
|
[Symbol.iterator](): Iterator<Quad>;
|
|
293
318
|
dispose(): void;
|
|
@@ -380,6 +405,12 @@ export interface ParseOptions {
|
|
|
380
405
|
* with one diagnostic of class 'too-many-errors'. Default: no limit.
|
|
381
406
|
*/
|
|
382
407
|
maxErrors?: number;
|
|
408
|
+
/**
|
|
409
|
+
* Read JSON-LD as JSON-LD-star (`@triple`, `@reifies`, `@annotation` as
|
|
410
|
+
* RDF 1.2 triple terms and reifiers), as `jsonldToRdf` does. Format
|
|
411
|
+
* 'jsonld' only (given or inferred); not with `lenient`. Default: false.
|
|
412
|
+
*/
|
|
413
|
+
rdfstar?: boolean;
|
|
383
414
|
}
|
|
384
415
|
|
|
385
416
|
export interface QueryOptions extends DatasetQueryOptions {
|
|
@@ -535,17 +566,24 @@ export function canonicalize(
|
|
|
535
566
|
export function graphs(dataset: Dataset): Array<[name: NamedNode | BlankNode, graph: Dataset]>;
|
|
536
567
|
|
|
537
568
|
/**
|
|
538
|
-
* The RDFC-1.0 canonical hash of a
|
|
539
|
-
* canonical N-Quads document
|
|
540
|
-
* Dataset Canonicalization 1.0, section 4.4 note 2)
|
|
541
|
-
* the canonical form and the digest.
|
|
542
|
-
* dropped first, so
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
*
|
|
569
|
+
* The RDFC-1.0 canonical hash of a dataset: the SHA-256, as 64 lowercase
|
|
570
|
+
* hexadecimal digits, of the canonical N-Quads document that canonicalize()
|
|
571
|
+
* answers (RDF Dataset Canonicalization 1.0, section 4.4 note 2), graph names
|
|
572
|
+
* included. The engine computes the canonical form and the digest. Since
|
|
573
|
+
* 0.20.0; 0.17.0 to 0.19.x dropped every graph name first, so datasets that
|
|
574
|
+
* differ only in their graph names got the same hash. To hash a graph
|
|
575
|
+
* whatever its name (for example one entry of graphs()), use
|
|
576
|
+
* canonicalHash(asDefaultGraph(g)). Rejects when the input holds an RDF 1.2
|
|
577
|
+
* triple term or the section 4.4 call budget is exceeded.
|
|
578
|
+
*/
|
|
579
|
+
export function canonicalHash(dataset: Dataset): Promise<string>;
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* A new Dataset with the triples of every graph of `dataset`, all in the
|
|
583
|
+
* default graph (the engine's union of the graphs). With one entry of
|
|
584
|
+
* graphs(), it is that graph without its name. Dispose of it when done.
|
|
547
585
|
*/
|
|
548
|
-
export function
|
|
586
|
+
export function asDefaultGraph(dataset: Dataset): Dataset;
|
|
549
587
|
|
|
550
588
|
/**
|
|
551
589
|
* Whether two datasets are isomorphic (RDF 1.1 Concepts 3.6 and 4; blank
|
|
@@ -561,9 +599,137 @@ export function fromQuads(quads: Iterable<Quad>): Promise<Dataset>;
|
|
|
561
599
|
/** Load the engine. Afterwards the N-Quads text functions of `@factoidal/core/rdfjs` work. */
|
|
562
600
|
export function ready(): Promise<void>;
|
|
563
601
|
|
|
602
|
+
// ---------------------------------------------------------------------
|
|
603
|
+
// Literal values (https://github.com/danbri/factoidal/issues/1051 items 1-3).
|
|
604
|
+
// Synchronous after the engine is loaded (`await ready()` or any other call);
|
|
605
|
+
// before that they throw a FactoidalError. The engine decides everything
|
|
606
|
+
// (formal/lean4/L4Factoidal/RDF/LiteralValue.lean). API.md "Literal values".
|
|
607
|
+
// ---------------------------------------------------------------------
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* The value of a literal, as JSON-safe data. A number that a JavaScript
|
|
611
|
+
* number may not hold exactly is a decimal string; `number` is present only
|
|
612
|
+
* when the value is exactly a binary64 value. Integer components are numbers
|
|
613
|
+
* when |n| <= 2^53 - 1, else decimal strings.
|
|
614
|
+
*/
|
|
615
|
+
export type LiteralValueData =
|
|
616
|
+
| { kind: 'string' | 'anyURI'; string: string }
|
|
617
|
+
| { kind: 'boolean'; boolean: boolean }
|
|
618
|
+
| { kind: 'decimal'; decimal: string; integer: boolean; number?: number }
|
|
619
|
+
| { kind: 'float' | 'double'; decimal?: string; number: number;
|
|
620
|
+
negativeZero?: true; special?: 'NaN' | 'INF' | '-INF' }
|
|
621
|
+
| { kind: 'duration'; months: number | string; seconds: string }
|
|
622
|
+
| { kind: 'dateTime' | 'time' | 'date' | 'gYearMonth' | 'gYear' | 'gMonthDay' | 'gDay' | 'gMonth';
|
|
623
|
+
year?: number | string; month?: number; day?: number; hour?: number;
|
|
624
|
+
minute?: number; second?: string; timezoneOffset?: number }
|
|
625
|
+
| { kind: 'hexBinary' | 'base64Binary'; hex: string }
|
|
626
|
+
| { kind: 'QName' | 'NOTATION'; prefix: string; localName: string }
|
|
627
|
+
| { kind: 'list'; items: LiteralValueData[] }
|
|
628
|
+
| { kind: 'langString'; string: string; language: string; direction?: 'ltr' | 'rtl' };
|
|
629
|
+
|
|
630
|
+
export interface LiteralValueResult {
|
|
631
|
+
/** The datatype IRI. */
|
|
632
|
+
datatype: string;
|
|
633
|
+
/** false: the engine has no lexical space for this datatype. */
|
|
634
|
+
recognized: boolean;
|
|
635
|
+
/** The lexical form is in the lexical space (null when not recognized). */
|
|
636
|
+
valid: boolean | null;
|
|
637
|
+
/** Present for a valid literal of a datatype with a value model. */
|
|
638
|
+
value?: LiteralValueData;
|
|
639
|
+
/** The canonical lexical form (XSD 1.1 Part 2 section 2.3.1), when known. */
|
|
640
|
+
canonical?: string;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/** The XSD lexical-to-value mapping of a literal (RDF 1.1 Semantics section 7: no whiteSpace processing). */
|
|
644
|
+
export function literalValue(term: Literal): LiteralValueResult;
|
|
645
|
+
|
|
646
|
+
/** Whether the lexical form is in the datatype's lexical space; null when the engine has no lexical space for the datatype. */
|
|
647
|
+
export function isValidLiteral(term: Literal): boolean | null;
|
|
648
|
+
|
|
649
|
+
/** The literal with the canonical form of its value; null when it is not valid or has no canonical mapping. */
|
|
650
|
+
export function canonicalLiteral(term: Literal): Literal | null;
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* The literal of a JavaScript value. With no datatype the engine's table
|
|
654
|
+
* chooses: boolean xsd:boolean, string xsd:string, bigint xsd:integer, a safe
|
|
655
|
+
* integer Number xsd:integer, any other Number xsd:double, Date xsd:dateTime
|
|
656
|
+
* (UTC). `datatype` (an IRI, a NamedNode, or an XSD local name such as 'int')
|
|
657
|
+
* names the datatype; the value must be in its value space, else a
|
|
658
|
+
* FactoidalError with code 'literal.value'.
|
|
659
|
+
*/
|
|
660
|
+
export function literalFromValue(
|
|
661
|
+
value: boolean | number | bigint | string | Date,
|
|
662
|
+
options?: { datatype?: string | NamedNode }
|
|
663
|
+
): Literal;
|
|
664
|
+
|
|
564
665
|
/** The engine's name tables: format names, entailment regimes, query outputs, pack syntaxes. */
|
|
565
666
|
export function engineTables(): Promise<Record<string, unknown>>;
|
|
566
667
|
|
|
668
|
+
/**
|
|
669
|
+
* How Dataset.has, match and delete compare the object position
|
|
670
|
+
* (https://github.com/danbri/factoidal/issues/1052). 'term' (the default):
|
|
671
|
+
* RDF term equality. 'value': a literal object matches by value (sameValue()).
|
|
672
|
+
*/
|
|
673
|
+
export interface MatchOptions {
|
|
674
|
+
match?: 'term' | 'value';
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* SPARQL 1.1 `=` on two RDF terms (sections 17.3 and 17.4.1.7), decided by the
|
|
679
|
+
* engine: `true` the same value (`"01"^^xsd:integer` and `"1.0"^^xsd:decimal`),
|
|
680
|
+
* `false` different values, `null` incomparable (the operator's type error:
|
|
681
|
+
* two different literals of an unknown datatype, an ill-typed literal and
|
|
682
|
+
* another literal, `xsd:integer` and `xsd:boolean`). `"NaN"^^xsd:double` is
|
|
683
|
+
* not the same value as itself. A term is an RDF/JS term or an N-Triples term
|
|
684
|
+
* string. Synchronous: the engine must be loaded (`await ready()`).
|
|
685
|
+
*/
|
|
686
|
+
export function sameValue(a: Term | string, b: Term | string): boolean | null;
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* The syntax of a document by its file name (or IRI path; the query and the
|
|
690
|
+
* fragment are ignored) and its media type, from the engine's table of the
|
|
691
|
+
* W3C registrations (https://github.com/danbri/factoidal/issues/1053): Turtle
|
|
692
|
+
* `text/turtle` `.ttl`, N-Triples `application/n-triples` `.nt`, N-Quads
|
|
693
|
+
* `application/n-quads` `.nq`, TriG `application/trig` `.trig`, RDF/XML
|
|
694
|
+
* `application/rdf+xml` `.rdf`, JSON-LD `application/ld+json` `.jsonld`. The
|
|
695
|
+
* media type wins when it is given (its parameters are ignored); an unknown
|
|
696
|
+
* media type does not fall back to the name. Answers a `name` of formats(),
|
|
697
|
+
* or `null`. Synchronous: the engine must be loaded (`await ready()`).
|
|
698
|
+
*/
|
|
699
|
+
export function syntaxFor(what: string | { fileName?: string; mediaType?: string }): string | null;
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* An IRI as a namespace and a local name: the local name is the longest
|
|
703
|
+
* suffix that is an XML NCName (what an RDF/XML QName can carry), `''` when
|
|
704
|
+
* there is none; `namespace + localName` is the IRI
|
|
705
|
+
* (https://github.com/danbri/factoidal/issues/1051 item 4). Synchronous.
|
|
706
|
+
*/
|
|
707
|
+
export function splitIri(iri: string | NamedNode): { namespace: string; localName: string };
|
|
708
|
+
|
|
709
|
+
/** Is the text an XML NCName (Namespaces in XML 1.0, production [4])? A prefix label check. Synchronous. */
|
|
710
|
+
export function isNCName(text: string): boolean;
|
|
711
|
+
|
|
712
|
+
/** One row of the engine's vocabulary table. A term IRI is `namespace + term`. */
|
|
713
|
+
export interface VocabularyRow {
|
|
714
|
+
prefix: string;
|
|
715
|
+
namespace: string;
|
|
716
|
+
/** Local names; empty for a namespace whose vocabulary is not in the engine table. */
|
|
717
|
+
terms: string[];
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* The engine's vocabulary table (https://github.com/danbri/factoidal/issues/1051
|
|
722
|
+
* item 5): rdf, rdfs, xsd and owl with their terms; foaf, dcterms, dc and
|
|
723
|
+
* schema as namespaces only. The prefixes are those of the Turtle writer. Synchronous.
|
|
724
|
+
*/
|
|
725
|
+
export function vocabularies(): VocabularyRow[];
|
|
726
|
+
|
|
727
|
+
/** The container membership property `rdf:_n` (n >= 1). Synchronous. */
|
|
728
|
+
export function memberIri(n: number): NamedNode;
|
|
729
|
+
|
|
730
|
+
/** The `n` of `rdf:_n` (no leading zero, n >= 1), or `null` for any other IRI. Synchronous. */
|
|
731
|
+
export function memberOrdinal(iri: string | NamedNode): number | null;
|
|
732
|
+
|
|
567
733
|
/** A SHACL validation-report term (see shaclValidate). */
|
|
568
734
|
export interface ShaclValidateResult {
|
|
569
735
|
conforms: boolean;
|
|
@@ -758,7 +924,14 @@ export interface EvidenceRecord {
|
|
|
758
924
|
outside?: OutsideSetting[];
|
|
759
925
|
}
|
|
760
926
|
|
|
761
|
-
/**
|
|
927
|
+
/**
|
|
928
|
+
* The value on a wire. After a node, `graph` is a value of the node's
|
|
929
|
+
* `wireOut`: a Dataset for the graph wires, text for String (a writer), the
|
|
930
|
+
* rows for Table (SELECT), a boolean for Answer (ASK), `[canonical, sha256]`
|
|
931
|
+
* for String × String (rdfcStage), the report object for ValidationReport,
|
|
932
|
+
* the explain result for ExplainGraphResult. Since 0.20.0; before, a node
|
|
933
|
+
* whose output was not a Dataset left its input on the wire.
|
|
934
|
+
*/
|
|
762
935
|
export interface Wire<G = unknown> {
|
|
763
936
|
graph: G;
|
|
764
937
|
evidence: EvidenceRecord[];
|
|
@@ -783,7 +956,12 @@ export interface FactoidalNode {
|
|
|
783
956
|
readonly wireOut: string;
|
|
784
957
|
readonly runnable: boolean;
|
|
785
958
|
readonly bound: boolean;
|
|
786
|
-
/**
|
|
959
|
+
/**
|
|
960
|
+
* The node's own copy of the settings as given (passed to the package
|
|
961
|
+
* function that runs the stage): frozen at every depth, a Dataset cloned,
|
|
962
|
+
* taken when node() checked them. A later change to the caller's objects
|
|
963
|
+
* does not reach the node; a change to a Dataset here makes run() refuse.
|
|
964
|
+
*/
|
|
787
965
|
readonly params: Readonly<Record<string, unknown>>;
|
|
788
966
|
/** The settings as sent to the engine: JSON values, a Dataset as {$nquads}. */
|
|
789
967
|
readonly settingsWire: Readonly<Record<string, unknown>>;
|
|
@@ -876,8 +1054,11 @@ export function pipe(...nodes: Array<FactoidalNode | Pipeline>): Pipeline;
|
|
|
876
1054
|
* Run a node or pipeline on `input` (a Wire, or the graph: text for a
|
|
877
1055
|
* reader, else a Dataset or data input). Rejects before any node runs when
|
|
878
1056
|
* a node's stage has status 'missing' (unless `options.unchecked`) or has
|
|
879
|
-
* no package function,
|
|
880
|
-
* well typed (unless `options.unchecked`; then `proved` is false)
|
|
1057
|
+
* no package function, when the engine's check finds the pipeline not
|
|
1058
|
+
* well typed (unless `options.unchecked`; then `proved` is false), or when a
|
|
1059
|
+
* node's settings changed after node() checked them. Rejects with code
|
|
1060
|
+
* 'op.failed' when a node's runner gives a value that is not of the node's
|
|
1061
|
+
* `wireOut` (see Wire).
|
|
881
1062
|
*/
|
|
882
1063
|
export function run(pipeline: FactoidalNode | Pipeline, input: unknown, options?: RunOptions): Promise<RunResult>;
|
|
883
1064
|
|
|
@@ -1191,6 +1372,8 @@ export interface Sbm11Store {
|
|
|
1191
1372
|
/** the generation CURRENT names, or "" when the source is a generation */
|
|
1192
1373
|
generation: string;
|
|
1193
1374
|
terms: number;
|
|
1375
|
+
/** how the engine checks reads; undefined from a wasm module built before the Merkle check */
|
|
1376
|
+
verify: 'merkle' | 'none' | undefined;
|
|
1194
1377
|
query(sparql: string, options?: { base?: string; sparql12?: boolean; reference?: boolean }): Sbm11Answer;
|
|
1195
1378
|
/** the resources the reader read, when its reader records them (lwsSbm11Reader) */
|
|
1196
1379
|
readonly evidence: Sbm11ReadEvidence[] | undefined;
|
|
@@ -1198,8 +1381,11 @@ export interface Sbm11Store {
|
|
|
1198
1381
|
}
|
|
1199
1382
|
|
|
1200
1383
|
/** Open an SBM11 generation (https://github.com/danbri/factoidal/issues/1009).
|
|
1201
|
-
* Node: `source` is a directory unless a reader is given or registered.
|
|
1202
|
-
|
|
1384
|
+
* Node: `source` is a directory unless a reader is given or registered.
|
|
1385
|
+
* `verify` (default 'merkle'): the engine checks every byte it decodes against
|
|
1386
|
+
* the manifest's Merkle roots and refuses a changed file with its name;
|
|
1387
|
+
* 'none' checks lengths only. */
|
|
1388
|
+
export function openSbm11(source: string, options?: { reader?: Sbm11Reader; verify?: 'merkle' | 'none' }): Promise<Sbm11Store>;
|
|
1203
1389
|
|
|
1204
1390
|
/** Serve `source` with `reader`; `null` removes it. */
|
|
1205
1391
|
export function registerSbm11Source(source: string, reader: Sbm11Reader | null): void;
|
|
@@ -1679,6 +1865,8 @@ export function capabilities(): Promise<{
|
|
|
1679
1865
|
store: boolean;
|
|
1680
1866
|
/** The deltaLog* functions (deltaLogEncode, deltaLogDecode, deltaLogMerge). */
|
|
1681
1867
|
deltaLog: boolean;
|
|
1868
|
+
/** ops literalValue and literalFromValue (issue 1051). */
|
|
1869
|
+
literalValues: boolean;
|
|
1682
1870
|
/** 'full': the whole library is in the wasm module. */
|
|
1683
1871
|
profile: 'full' | string;
|
|
1684
1872
|
/** The dispatch ABI version string of the loaded wasm module. */
|
|
@@ -1762,10 +1950,18 @@ declare const _default: {
|
|
|
1762
1950
|
canonicalize: typeof canonicalize;
|
|
1763
1951
|
graphs: typeof graphs;
|
|
1764
1952
|
canonicalHash: typeof canonicalHash;
|
|
1953
|
+
asDefaultGraph: typeof asDefaultGraph;
|
|
1765
1954
|
isomorphic: typeof isomorphic;
|
|
1766
1955
|
fromQuads: typeof fromQuads;
|
|
1767
1956
|
ready: typeof ready;
|
|
1768
1957
|
engineTables: typeof engineTables;
|
|
1958
|
+
sameValue: typeof sameValue;
|
|
1959
|
+
syntaxFor: typeof syntaxFor;
|
|
1960
|
+
splitIri: typeof splitIri;
|
|
1961
|
+
isNCName: typeof isNCName;
|
|
1962
|
+
vocabularies: typeof vocabularies;
|
|
1963
|
+
memberIri: typeof memberIri;
|
|
1964
|
+
memberOrdinal: typeof memberOrdinal;
|
|
1769
1965
|
shaclValidate: typeof shaclValidate;
|
|
1770
1966
|
shexValidate: typeof shexValidate;
|
|
1771
1967
|
owlClosure: typeof owlClosure;
|
|
@@ -1821,6 +2017,10 @@ declare const _default: {
|
|
|
1821
2017
|
FactoidalError: typeof FactoidalError;
|
|
1822
2018
|
dataFactory: DataFactory;
|
|
1823
2019
|
queryRaw: typeof queryRaw;
|
|
2020
|
+
literalValue: typeof literalValue;
|
|
2021
|
+
isValidLiteral: typeof isValidLiteral;
|
|
2022
|
+
canonicalLiteral: typeof canonicalLiteral;
|
|
2023
|
+
literalFromValue: typeof literalFromValue;
|
|
1824
2024
|
version: string;
|
|
1825
2025
|
engine: string;
|
|
1826
2026
|
};
|
package/index.mjs
CHANGED
|
@@ -55,10 +55,24 @@ export const serialize = api.serialize;
|
|
|
55
55
|
export const canonicalize = api.canonicalize;
|
|
56
56
|
export const graphs = api.graphs;
|
|
57
57
|
export const canonicalHash = api.canonicalHash;
|
|
58
|
+
export const asDefaultGraph = api.asDefaultGraph;
|
|
58
59
|
export const isomorphic = api.isomorphic;
|
|
59
60
|
export const fromQuads = api.fromQuads;
|
|
61
|
+
// Literal values (https://github.com/danbri/factoidal/issues/1051): synchronous
|
|
62
|
+
// after the engine is loaded.
|
|
63
|
+
export const literalValue = api.literalValue;
|
|
64
|
+
export const isValidLiteral = api.isValidLiteral;
|
|
65
|
+
export const canonicalLiteral = api.canonicalLiteral;
|
|
66
|
+
export const literalFromValue = api.literalFromValue;
|
|
60
67
|
export const ready = api.ready;
|
|
61
68
|
export const engineTables = api.engineTables;
|
|
69
|
+
export const sameValue = api.sameValue;
|
|
70
|
+
export const syntaxFor = api.syntaxFor;
|
|
71
|
+
export const splitIri = api.splitIri;
|
|
72
|
+
export const isNCName = api.isNCName;
|
|
73
|
+
export const vocabularies = api.vocabularies;
|
|
74
|
+
export const memberIri = api.memberIri;
|
|
75
|
+
export const memberOrdinal = api.memberOrdinal;
|
|
62
76
|
export const openDataset = api.openDataset;
|
|
63
77
|
export const closure = api.closure;
|
|
64
78
|
export const formats = api.formats;
|
package/l4-assets/l4factoidal.js
CHANGED
|
Binary file
|
package/l4-assets/version.json
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
"engine": "lean4",
|
|
3
3
|
"note": "The Lean 4 (L4Factoidal) engine build provenance and claims: the only engine of @factoidal/core since 0.9.0 (issue 713). This committed file is a placeholder. tools/fetch-builds.sh --set web (through tools/stamp-l4-version.mjs) writes the provenance members from the danbri/factoidal-builds release that built the wasm; formal/lean4/Wasm/build-wasm.sh step 9 writes them for a local build. Do not commit a stamped copy.",
|
|
4
4
|
"stamped": true,
|
|
5
|
-
"release": "danbri/factoidal-builds build-
|
|
6
|
-
"releaseRun": "https://github.com/danbri/factoidal-builds/actions/runs/
|
|
7
|
-
"gitSha": "
|
|
8
|
-
"builtAt": "2026-10-
|
|
5
|
+
"release": "danbri/factoidal-builds build-0c9a222bdb25-web",
|
|
6
|
+
"releaseRun": "https://github.com/danbri/factoidal-builds/actions/runs/40662145237",
|
|
7
|
+
"gitSha": "0c9a222bdb25ff70456611d3fbc87a41902d8324",
|
|
8
|
+
"builtAt": "2026-10-28T09:52:07Z",
|
|
9
9
|
"leanToolchain": "leanprover/lean4:v4.33.1",
|
|
10
10
|
"emscripten": "6.0.8",
|
|
11
11
|
"abiVersion": "1",
|
|
12
12
|
"engineVersion": "l4factoidal-wasm 0.2.0 (dispatch: RDF parse/serialize, SPARQL query+update, RDFS/OWL-RL closures, RDFC-1.0, CL/IKL)",
|
|
13
13
|
"version": "l4factoidal-wasm 0.2.0 (dispatch: RDF parse/serialize, SPARQL query+update, RDFS/OWL-RL closures, RDFC-1.0, CL/IKL)",
|
|
14
|
-
"wasmSha256": "
|
|
15
|
-
"wasmBytes":
|
|
14
|
+
"wasmSha256": "43c334ec53357cd40339f693d303bda3e422ac92e94ad335cb6b0e83ec4eafbd",
|
|
15
|
+
"wasmBytes": 17958911,
|
|
16
16
|
"claims": {
|
|
17
17
|
"source": "formal/lean4 (L4Factoidal): no sorry, no user axioms, no native_decide; W3C behaviour pinned by build-time #guard",
|
|
18
18
|
"suitesAtBuildSha": "see docs/test-results and formal/lean4/PORT_NOTES.md at gitSha"
|