diff --git a/package-lock.json b/package-lock.json index 1adf2e4..2b7e2a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "quadstore", - "version": "15.2.0", + "version": "15.3.0-beta.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "quadstore", - "version": "15.2.0", + "version": "15.3.0-beta.1", "license": "MIT", "dependencies": { "@rdfjs/types": "^2.0.1", diff --git a/package.json b/package.json index 382e75a..7943b6e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "quadstore", - "version": "15.2.0", + "version": "15.3.0-beta.1", "description": "Quadstore is a LevelDB-backed RDF graph database / triplestore for JavaScript runtimes (browsers, Node.js, Deno, Bun, ...) that implements the RDF/JS interfaces and supports SPARQL queries and querying across named graphs.", "keywords": [ "node", diff --git a/src/serialization/fpstring.ts b/src/serialization/fpstring.ts index 87657be..976b65e 100644 --- a/src/serialization/fpstring.ts +++ b/src/serialization/fpstring.ts @@ -44,6 +44,8 @@ * +------+------------+-----------------------------------------+--------------------+------------+ * | 6 | Infinity | | | | * +------+------------+-----------------------------------------+--------------------+------------+ + * | 7 | NaN | | | | + * +------+------------+-----------------------------------------+--------------------+------------+ * */ @@ -64,6 +66,7 @@ const join = (encodingCase: number, exponent: number, mantissa: number): string const ZERO = join(3, 0, 0); const NEG_INF = join(0, 0, 0); const POS_INF = join(6, 0, 0); +const NAN = join(7, 0, 0); export const encode = (stringOrNumber: string|number): string => { @@ -72,7 +75,7 @@ export const encode = (stringOrNumber: string|number): string => { : stringOrNumber; if (Number.isNaN(mantissa)) { - throw new Error(`Cannot serialize NaN`); + return NAN; } if (mantissa === -Infinity) { diff --git a/src/serialization/terms.ts b/src/serialization/terms.ts index 1dd05a5..9035ff0 100644 --- a/src/serialization/terms.ts +++ b/src/serialization/terms.ts @@ -169,6 +169,7 @@ export const termWriter: TermWriter = { stringLiteralWriter.write(term, serialized, prefixes); break; case xsd.integer: + case xsd.float: case xsd.double: case xsd.decimal: case xsd.nonPositiveInteger: diff --git a/src/serialization/xsd.ts b/src/serialization/xsd.ts index 94289a0..d0c4578 100644 --- a/src/serialization/xsd.ts +++ b/src/serialization/xsd.ts @@ -12,6 +12,7 @@ export const boolean = `${xsd}boolean`; export const integer = `${xsd}integer`; export const decimal = `${xsd}decimal`; +export const float = `${xsd}float`; export const double = `${xsd}double`; export const nonPositiveInteger = `${xsd}nonPositiveInteger`; export const negativeInteger = `${xsd}negativeInteger`; diff --git a/test/quadstore/serialization.ts b/test/quadstore/serialization.ts index 144bd98..db129ca 100644 --- a/test/quadstore/serialization.ts +++ b/test/quadstore/serialization.ts @@ -103,6 +103,21 @@ export const runSerializationTests = () => { toEqualQuad(read, quad); }); }); + + it('Should serialize and deserialize a quad having a NaN literal term', async function () { + const { store: { dataFactory: factory, indexes }, prefixes } = this; + const quad = factory.quad( + factory.namedNode('http://ex.com/s'), + factory.namedNode('http://ex.com/p'), + factory.literal('NaN', factory.namedNode(xsd.double)), + factory.namedNode('http://ex.com/g'), + ); + indexes.forEach((index: InternalIndex) => { + const key = twoStepsQuadWriter.ingest(quad, prefixes).write(index.prefix, index.terms); + const read = quadReader.read(key, index.prefix.length, index.terms, factory, prefixes); + toEqualQuad(read, quad); + }); + }); });