@factoidal/core 0.11.0 → 0.13.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/browser.d.ts CHANGED
@@ -5,6 +5,8 @@
5
5
  // system, so a path string rejects.
6
6
 
7
7
  export type {
8
+ FactoidalErrorCode,
9
+ FactoidalErrorPosition,
8
10
  NamedNode, BlankNode, Literal, Variable, DefaultGraph, Quad, Term, DataFactory,
9
11
  DataFormat, EntailRegime, Bindings, DataInput, QueryInput, ParseOptions,
10
12
  QueryOptions, SerializeOptions, StoreReader, OpenStoreOptions,
@@ -89,9 +91,8 @@ export {
89
91
  didKeyResolve,
90
92
  capabilities,
91
93
  Dataset,
92
- DatasetHandle,
93
94
  Store,
94
- ParseError,
95
+ FactoidalError,
95
96
  dataFactory,
96
97
  version,
97
98
  engine,
package/browser.js CHANGED
@@ -153,9 +153,8 @@ export const didKeyResolve = api.didKeyResolve;
153
153
  // Types, probes and metadata
154
154
  export const capabilities = api.capabilities;
155
155
  export const Dataset = api.Dataset;
156
- export const DatasetHandle = api.DatasetHandle;
157
156
  export const Store = api.Store;
158
- export const ParseError = api.ParseError;
157
+ export const FactoidalError = api.FactoidalError;
159
158
  export const dataFactory = api.dataFactory;
160
159
  export const version = api.version;
161
160
  export const engine = api.engine;
package/fn.js CHANGED
@@ -252,7 +252,7 @@ function builder() {
252
252
  let finished = false;
253
253
  return {
254
254
  addChunk(chunk) {
255
- if (finished) throw new Error('builder: addChunk() called after finish()');
255
+ if (finished) throw new engineApi.FactoidalError('builder: addChunk() called after finish()', { code: 'op.failed' });
256
256
  if (chunk && typeof chunk.termType === 'string') {
257
257
  pending.push(chunk); // a single Quad
258
258
  } else {
@@ -260,7 +260,7 @@ function builder() {
260
260
  }
261
261
  },
262
262
  finish() {
263
- if (finished) throw new Error('builder: finish() already called');
263
+ if (finished) throw new engineApi.FactoidalError('builder: finish() already called', { code: 'op.failed' });
264
264
  finished = true;
265
265
  const result = makeFnDataset(pending);
266
266
  pending = null; // release; no further mutation is possible anyway
@@ -354,24 +354,20 @@ async function query(ds, sparql, options) {
354
354
  * per-graph closure semantics that the underlying query() does not
355
355
  * define today.
356
356
  */
357
- // The regime names, their case-insensitive aliases and the x-ikl-* refusal
358
- // are the engine's tables (op engineTables): no host copy
357
+ // The regime names and their case-insensitive aliases are the engine's tables
358
+ // (op engineTables): no host copy
359
359
  // (https://github.com/danbri/factoidal/issues/894 item 5). A name with no
360
- // alias passes through unchanged and engineApi.query reports it.
361
- async function regimeOf(regime, who) {
360
+ // alias passes through unchanged and engineApi.query refuses it with the
361
+ // engine's code (regime.refused for x-ikl-*, option.invalid-value otherwise).
362
+ async function regimeOf(regime) {
362
363
  const t = await engineApi.engineTables();
363
364
  const r = regime == null ? 'none' : String(regime);
364
- for (const [prefix, message] of Object.entries(t.refusedRegimePrefixes)) {
365
- if (r.toLowerCase().startsWith(prefix)) {
366
- throw new TypeError(message.replace('WHO', who).replace('REGIME', r));
367
- }
368
- }
369
365
  return t.entailAliases[r.toLowerCase()] || regime;
370
366
  }
371
367
 
372
368
  async function entail(ds, regime) {
373
369
  assertFnDataset(ds, 'entail');
374
- const entailRegime = await regimeOf(regime, 'entail');
370
+ const entailRegime = await regimeOf(regime);
375
371
  const rows = await engineApi.query((await engineOf(ds)), 'SELECT ?s ?p ?o WHERE { ?s ?p ?o }',
376
372
  { entail: entailRegime });
377
373
  return makeFnDataset(
package/index.d.ts CHANGED
@@ -84,27 +84,85 @@ export interface DataFactory {
84
84
  export const dataFactory: DataFactory;
85
85
 
86
86
  /**
87
- * A parse failure that carries a position (issue #344): `line`/
88
- * `column`/`offset` are set when the failing engine call reported one
89
- * (Turtle, TriG, N-Triples, N-Quads); `undefined` for an RDF/XML or
90
- * JSON-LD failure, or any non-parse engine error, which stay a plain
91
- * `Error`. `name` is `'ParseError'`.
87
+ * The stable error codes. The engine decides the code of every refusal
88
+ * (formal/lean4/Wasm/Ops/ErrorModel.lean); `engineTables().errorCodes` lists
89
+ * each with its specification section and summary, and the README table
90
+ * "Errors" is generated from that list. `host.io` is a failure of
91
+ * the host (file system, IndexedDB), not of the engine.
92
92
  */
93
- export class ParseError extends Error {
94
- readonly name: 'ParseError';
95
- /** 1-based line of the error. */
96
- readonly line?: number;
97
- /** 1-based column of the error, counted in Unicode scalar values. */
98
- readonly column?: number;
93
+ export type FactoidalErrorCode =
94
+ | 'parse.syntax'
95
+ | 'parse.rdf12-required'
96
+ | 'term.invalid-iri'
97
+ | 'term.invalid-langtag'
98
+ | 'term.invalid'
99
+ | 'query.syntax'
100
+ | 'query.failed'
101
+ | 'update.syntax'
102
+ | 'update.failed'
103
+ | 'format.unknown'
104
+ | 'serialize.unsupported-rdf12'
105
+ | 'serialize.failed'
106
+ | 'canon.unsupported-rdf12'
107
+ | 'canon.failed'
108
+ | 'owl.unsupported-rdf12'
109
+ | 'reason.failed'
110
+ | 'regime.refused'
111
+ | 'validate.failed'
112
+ | 'xml.failed'
113
+ | 'crypto.failed'
114
+ | 'store.failed'
115
+ | 'registry.failed'
116
+ | 'handle.unknown'
117
+ | 'handle.disposed'
118
+ | 'option.unknown'
119
+ | 'option.invalid-value'
120
+ | 'option.conflict'
121
+ | 'capacity.exceeded'
122
+ | 'call.arity'
123
+ | 'call.arguments'
124
+ | 'op.unknown'
125
+ | 'op.failed'
126
+ | 'host.io';
127
+
128
+ /** Where in the input a FactoidalError happened. */
129
+ export interface FactoidalErrorPosition {
130
+ /** 1-based line. */
131
+ line: number;
132
+ /** 1-based column, counted in Unicode scalar values. */
133
+ column: number;
99
134
  /**
100
- * The position of the error as a UTF-16 code-unit index into the input
101
- * JavaScript string: `text.slice(err.offset)` starts at the error. A
102
- * character outside the Basic Multilingual Plane (U+10000 and above)
103
- * counts 2, as in every JavaScript string index. (The engine reports a
104
- * count of Unicode scalar values; the wrapper converts.)
135
+ * A UTF-16 code-unit index into the input JavaScript string:
136
+ * `text.slice(err.position.offset)` starts at the error.
105
137
  */
106
- readonly offset?: number;
138
+ offset: number;
139
+ /** The same position as a count of UTF-8 bytes from the start of the input. */
140
+ byteOffset: number;
141
+ }
142
+
143
+ /**
144
+ * The one error class of the package. Every function rejects (or throws)
145
+ * with it; a `TypeError` is thrown only when an argument has the wrong
146
+ * JavaScript type. The engine decides `code`, `spec` and `position`.
147
+ */
148
+ export class FactoidalError extends Error {
149
+ constructor(message: string, info?: {
150
+ code?: FactoidalErrorCode; position?: FactoidalErrorPosition | null;
151
+ spec?: string | null; cause?: unknown; format?: string; formatInferred?: boolean;
152
+ });
153
+ readonly name: 'FactoidalError';
154
+ /** The stable machine code. */
155
+ readonly code: FactoidalErrorCode;
156
+ /** Where the input defines a position (a parse, a query, an update), else null. */
157
+ readonly position: FactoidalErrorPosition | null;
158
+ /** The URL of the specification section that defines the condition, else null. */
159
+ readonly spec: string | null;
160
+ /** The underlying error, when there is one (host.io). */
161
+ readonly cause?: unknown;
162
+ /** For a parse failure of text: the syntax it was read as. */
107
163
  readonly format?: string;
164
+ /** For a parse failure of text: true when the syntax was inferred. */
165
+ readonly formatInferred?: boolean;
108
166
  }
109
167
 
110
168
  /** One recoverable-parse diagnostic from a `{lenient:true}` parse() call. */
@@ -112,7 +170,7 @@ export interface ParseDiagnostic {
112
170
  message: string;
113
171
  /**
114
172
  * The position of the error as a UTF-16 code-unit index into the input
115
- * JavaScript string, as ParseError.offset: `text.slice(d.offset)` starts
173
+ * JavaScript string, as FactoidalError.position.offset: `text.slice(d.offset)` starts
116
174
  * at the error.
117
175
  */
118
176
  offset: number;
@@ -222,8 +280,6 @@ export class Dataset implements Iterable<Quad> {
222
280
  [Symbol.dispose](): void;
223
281
  }
224
282
 
225
- /** @deprecated The name of Dataset before 0.10.0; removed in 0.11.0. */
226
- export const DatasetHandle: typeof Dataset;
227
283
 
228
284
  export type ClosureRegime = 'rdfs' | 'owl-rl' | 'rho-df' | 'rdfs-plus';
229
285
 
@@ -302,7 +358,7 @@ export interface ParseOptions {
302
358
  * entry per skipped statement. RDF/XML and JSON-LD parse strictly. A
303
359
  * document with no error gives the strict result and no diagnostics.
304
360
  * Default: false (strict; a syntax error, an undeclared prefix, or an
305
- * unresolvable relative IRI rejects the whole parse with a ParseError).
361
+ * unresolvable relative IRI rejects the whole parse with a FactoidalError).
306
362
  */
307
363
  lenient?: boolean;
308
364
  /**
@@ -323,7 +379,7 @@ export interface QueryOptions extends DatasetQueryOptions {
323
379
  * order is sorted (canonical N-Quads order), not document order;
324
380
  * anonymous blank-node labels (`_anonN`) DO reflect document order.
325
381
  * See README.md's "Blank nodes, labels and statement order". Strict
326
- * by default (issue #344): a syntax error rejects with a ParseError
382
+ * by default (issue #344): a syntax error rejects with a FactoidalError
327
383
  * (`line`/`column`/`offset` for Turtle/TriG/N-Triples/N-Quads; a
328
384
  * message only for RDF/XML and JSON-LD). `options.lenient` recovers
329
385
  * instead; see ParseOptions.
@@ -337,7 +393,7 @@ export function parse(text: string, options?: ParseOptions | DataFormat): Promis
337
393
  * Concise Bounded Description of each resource named). A `SERVICE <iri>`
338
394
  * whose IRI no registerServiceEndpoint() call named answers no
339
395
  * solutions even without SILENT
340
- * (https://github.com/danbri/factoidal/issues/717). `data` may be a DatasetHandle
396
+ * (https://github.com/danbri/factoidal/issues/717). `data` may be a Dataset
341
397
  * from openDataset(), in which case this routes to `data.query()` and
342
398
  * `options.entail` must be 'none' or omitted (a handle carries no
343
399
  * entailment-closure step).
@@ -447,7 +503,7 @@ export function serialize(
447
503
  /**
448
504
  * RDFC-1.0 dataset canonicalization: canonical blank-node labels plus
449
505
  * sorted canonical N-Quads. Two isomorphic inputs canonicalize to the
450
- * same string. `data` may be a DatasetHandle, in which case this
506
+ * same string. `data` may be a Dataset, in which case this
451
507
  * routes to `data.canonicalize()` (options are ignored for a handle).
452
508
  */
453
509
  export function canonicalize(
@@ -624,11 +680,16 @@ export function tableauDlInconsistent(
624
680
  ): Promise<{ inconsistent: boolean; rlAlone: boolean }>;
625
681
 
626
682
  /**
627
- * OWL DL consistency verdict via the clash-detecting tableau
628
- * (L4Factoidal/OWL/Refute.lean) over the OWL RL closure.
629
- * Default graph only. `consistent` is three-valued: `false` (a clash on
630
- * every branch), `true` (a model built), or `null` -- a budget-out, with
631
- * `reason` naming the fuel cap (never a silent false).
683
+ * Checked consistency for the original default graph in a restricted
684
+ * atomic OWL fragment (named subclass/class assertions, Thing/Nothing,
685
+ * sameAs/differentFrom and limited declarations/annotations).
686
+ * false requires an accepted certificate; null means unsupported-syntax
687
+ * or incomplete-search. No model producer exists, so true is not returned.
688
+ * Named graphs do not contribute axioms. RDF 1.2 terms are refused.
689
+ * This narrows earlier unchecked coverage: restrictions, object/data
690
+ * property axioms, imports and equivalentClass are unsupported.
691
+ * fuel is retained for compatibility but does not change this fixed
692
+ * 64-round certificate check. This is not complete OWL DL support.
632
693
  */
633
694
  export function owlIsConsistent(
634
695
  data: DataInput,
@@ -638,8 +699,13 @@ export function owlIsConsistent(
638
699
  /**
639
700
  * OWL entailment check: does `premise` entail `conclusion`? Two paths: `via: "closure"` (the conclusion is in the OWL-RL
640
701
  * closure of the premise) or `via: "refutation"` (the negated
641
- * conclusion is refuted on every goal). Default graph only. `entailed` is `true`, `false`, or `null`
642
- * (a refutation budget-out, with `reason` naming the cap).
702
+ * conclusion is refuted on every goal). Default graph only. The current
703
+ * implementation returns `true` for those positive results and `null`
704
+ * when it cannot establish entailment. `reason` distinguishes budget-out,
705
+ * incomplete-search, unsupported-conclusion and unsupported-punning.
706
+ * No checked countermodel constructor exists, so it never returns `false`.
707
+ * The punning refusal is limited; full OWL DL recognition and universal
708
+ * Direct Semantics soundness are not established by this API.
643
709
  */
644
710
  export function owlEntails(
645
711
  premise: DataInput,
@@ -1257,7 +1323,7 @@ export function capabilities(): Promise<{
1257
1323
  entailment: boolean;
1258
1324
  /** queryHdt() (op queryHdt) is served. */
1259
1325
  hdt: boolean;
1260
- /** query()'s `sparql12` and DatasetHandle.query's (queryDataset12, datasetQuery12). */
1326
+ /** query()'s `sparql12` and Dataset.query's (queryDataset12, datasetQuery12). */
1261
1327
  sparql12: boolean;
1262
1328
  /** openStore() and the Store methods (storeOpen, storeHandleQuery). */
1263
1329
  store: boolean;
@@ -1267,7 +1333,7 @@ export function capabilities(): Promise<{
1267
1333
  profile: 'full' | string;
1268
1334
  /** The dispatch ABI version string of the loaded wasm module. */
1269
1335
  abiVersion: string;
1270
- /** openDataset()/DatasetHandle (datasetOpen/Query/Update/Serialize/Close) are present. */
1336
+ /** openDataset()/Dataset (datasetOpen/Query/Update/Serialize/Close) are present. */
1271
1337
  datasetHandles: boolean;
1272
1338
  /** parse()'s `{lenient:true}` (parseDocument) is present. */
1273
1339
  parseDiagnostics: boolean;
@@ -1401,9 +1467,8 @@ declare const _default: {
1401
1467
  vcCheckRelatedResourceDigests: typeof vcCheckRelatedResourceDigests;
1402
1468
  capabilities: typeof capabilities;
1403
1469
  Dataset: typeof Dataset;
1404
- DatasetHandle: typeof DatasetHandle;
1405
1470
  Store: typeof Store;
1406
- ParseError: typeof ParseError;
1471
+ FactoidalError: typeof FactoidalError;
1407
1472
  dataFactory: DataFactory;
1408
1473
  queryRaw: typeof queryRaw;
1409
1474
  version: string;
package/index.mjs CHANGED
@@ -137,9 +137,8 @@ export const didKeyResolve = api.didKeyResolve;
137
137
  // Types, probes and metadata
138
138
  export const capabilities = api.capabilities;
139
139
  export const Dataset = api.Dataset;
140
- export const DatasetHandle = api.DatasetHandle;
141
140
  export const Store = api.Store;
142
- export const ParseError = api.ParseError;
141
+ export const FactoidalError = api.FactoidalError;
143
142
  export const dataFactory = api.dataFactory;
144
143
  export const version = api.version;
145
144
  export const engine = api.engine;
@@ -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 = "15eb8d770829";
40
+ const WASM_VERSION = "1b55f66d8e19";
41
41
 
42
42
  import createModule from './l4factoidal.mjs';
43
43
 
Binary file
@@ -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-d83100e6ec03-web",
6
- "releaseRun": "https://github.com/danbri/factoidal-builds/actions/runs/39574221615",
7
- "gitSha": "d83100e6ec038328a71a245e9fd10fbd768a38a5",
8
- "builtAt": "2026-10-21T09:44:37Z",
5
+ "release": "danbri/factoidal-builds build-6f5b96407a4c-web",
6
+ "releaseRun": "https://github.com/danbri/factoidal-builds/actions/runs/40076270080",
7
+ "gitSha": "6f5b96407a4cd95ac7452256ed2d4b9c938a7c49",
8
+ "builtAt": "2026-10-24T08:40:08Z",
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": "15eb8d770829f3f07dad4f8eabbbaf4503f55104a1803cb87209d05d093dc642",
15
- "wasmBytes": 12362890,
14
+ "wasmSha256": "1b55f66d8e193c6a3d168838bd77e8a5b1accb94e0a7c84209b63429f4989396",
15
+ "wasmBytes": 14483288,
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"