diff --git a/package-lock.json b/package-lock.json index 5485740..9a0883d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "shacl-tulip", - "version": "0.0.1", + "version": "0.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "shacl-tulip", - "version": "0.0.1", + "version": "0.0.2", "dependencies": { "@rdfjs/fetch-lite": "^3.3.0", "@rdfjs/formats-common": "^3.1.0", - "rdf-ext": "^2.5.2" + "n3": "^1.25.2" }, "devDependencies": { "happy-dom": "^17.2.2", @@ -82,20 +82,6 @@ "buffer": "^6.0.3" } }, - "node_modules/@digitalbazaar/http-client": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-3.4.1.tgz", - "integrity": "sha512-Ahk1N+s7urkgj7WvvUND5f8GiWEPfUw0D41hdElaqLgu8wZScI8gdI0q+qWw5N1d35x7GCRH2uk9mi+Uzo9M3g==", - "license": "BSD-3-Clause", - "dependencies": { - "ky": "^0.33.3", - "ky-universal": "^0.11.0", - "undici": "^5.21.2" - }, - "engines": { - "node": ">=14.0" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", @@ -521,15 +507,6 @@ "node": ">=18" } }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -559,21 +536,6 @@ "rdfjs-data-model-test": "bin/test.js" } }, - "node_modules/@rdfjs/dataset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@rdfjs/dataset/-/dataset-2.0.2.tgz", - "integrity": "sha512-6YJx+5n5Uxzq9dd9I0GGcIo6eopZOPfcsAfxSGX5d+YBzDgVa1cbtEBFnaPyPKiQsOm4+Cr3nwypjpg02YKPlA==", - "license": "MIT", - "bin": { - "rdfjs-dataset-test": "bin/test.js" - } - }, - "node_modules/@rdfjs/environment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@rdfjs/environment/-/environment-1.0.0.tgz", - "integrity": "sha512-+S5YjSvfoQR5r7YQCRCCVHvIEyrWia7FJv2gqM3s5EDfotoAQmFeBagApa9c/eQFi5EiNhmBECE5nB8LIxTaHg==", - "license": "MIT" - }, "node_modules/@rdfjs/fetch-lite": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/@rdfjs/fetch-lite/-/fetch-lite-3.3.0.tgz", @@ -585,22 +547,6 @@ "readable-stream": "^4.5.2" } }, - "node_modules/@rdfjs/formats": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@rdfjs/formats/-/formats-4.0.1.tgz", - "integrity": "sha512-Rg53vP+x1bnGAqJNKgEzJEUPDhj+tCpzb6wdmfLoVFq4XoZ589+cg2ScFDUMMyAVsgKXvSWjDhQ9f9ab254ZxA==", - "license": "MIT", - "dependencies": { - "@rdfjs/parser-jsonld": "^2.1.0", - "@rdfjs/parser-n3": "^2.0.1", - "@rdfjs/serializer-jsonld": "^2.0.0", - "@rdfjs/serializer-jsonld-ext": "^4.0.0", - "@rdfjs/serializer-ntriples": "^2.0.0", - "@rdfjs/serializer-turtle": "^1.1.1", - "@rdfjs/sink-map": "^2.0.0", - "rdfxml-streaming-parser": "^3.0.1" - } - }, "node_modules/@rdfjs/formats-common": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@rdfjs/formats-common/-/formats-common-3.1.0.tgz", @@ -615,54 +561,6 @@ "rdfxml-streaming-parser": "^2.2.0" } }, - "node_modules/@rdfjs/formats/node_modules/rdfxml-streaming-parser": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rdfxml-streaming-parser/-/rdfxml-streaming-parser-3.0.1.tgz", - "integrity": "sha512-lJtJ85xEJHc5BXohOPtxjYMEbGK3uiRxROwJLVNGanjuKLT9BWJluoNr3RzS9vQNmjkQwhhYmrbIftw1WUOj7Q==", - "license": "MIT", - "dependencies": { - "@rubensworks/saxes": "^6.0.1", - "@types/readable-stream": "^4.0.18", - "buffer": "^6.0.3", - "rdf-data-factory": "^2.0.0", - "readable-stream": "^4.4.2", - "relative-to-absolute-iri": "^1.0.0", - "validate-iri": "^1.0.0" - }, - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/rubensworks/" - } - }, - "node_modules/@rdfjs/io": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@rdfjs/io/-/io-1.2.0.tgz", - "integrity": "sha512-wGScmcUW7YAcoQk0bTRDBZqdPL/Y58Fuz7F0nXKThBnWPTIUct8CWKzbkT1ym8X/nW46yBw5+nmasVauSN7yIw==", - "license": "MIT", - "dependencies": { - "duplex-to": "^2.0.0", - "readable-stream": "^4.4.2", - "stream-chunks": "^1.0.0" - } - }, - "node_modules/@rdfjs/namespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@rdfjs/namespace/-/namespace-2.0.1.tgz", - "integrity": "sha512-U85NWVGnL3gWvOZ4eXwUcv3/bom7PAcutSBQqmVWvOaslPy+kDzAJCH1WYBLpdQd4yMmJ+bpJcDl9rcHtXeixg==", - "license": "MIT", - "dependencies": { - "@rdfjs/data-model": "^2.0.1" - } - }, - "node_modules/@rdfjs/normalize": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@rdfjs/normalize/-/normalize-2.0.3.tgz", - "integrity": "sha512-Zklg33Uc2R0wYiYw/OAe7IA3548h/EmN7Pf/RAj6gxkx5juRqbkMmjXYoYlFrV1ug4z1qC4RLgr69juA81kTGA==", - "license": "MIT", - "dependencies": { - "rdf-canonize": "^4.0.1" - } - }, "node_modules/@rdfjs/parser-jsonld": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/@rdfjs/parser-jsonld/-/parser-jsonld-2.1.3.tgz", @@ -689,27 +587,6 @@ "readable-stream": "^4.5.2" } }, - "node_modules/@rdfjs/prefix-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@rdfjs/prefix-map/-/prefix-map-0.1.2.tgz", - "integrity": "sha512-qapFYVPYyYepg0sFy7T512667iZsN9a3RNcyNBTBV+O8wrU3v/URQZOipCTNrEm1BXzZ7KCK1Yi8HrE1y+uRuQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "^4.3.0" - } - }, - "node_modules/@rdfjs/score": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@rdfjs/score/-/score-0.1.2.tgz", - "integrity": "sha512-HKiC6q6sCsEPYVf9B4k/R0Hd+9e0QsjKr4zRdfuv6V4VPiPyzHfAsSUiFfRdi8UvNfpdKmoSWX8PM/ZIPwvq1g==", - "license": "MIT", - "dependencies": { - "@rdfjs/data-model": "^2.0.2", - "@rdfjs/term-map": "^2.0.1", - "@rdfjs/term-set": "^2.0.2", - "@rdfjs/to-ntriples": "^3.0.1" - } - }, "node_modules/@rdfjs/serializer-jsonld": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@rdfjs/serializer-jsonld/-/serializer-jsonld-2.0.1.tgz", @@ -720,18 +597,6 @@ "readable-stream": "^4.5.2" } }, - "node_modules/@rdfjs/serializer-jsonld-ext": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@rdfjs/serializer-jsonld-ext/-/serializer-jsonld-ext-4.0.1.tgz", - "integrity": "sha512-eGNAdhsV8wkmCadyIN+PBfsN+BIiqplAd5VMc++wf5McsVi/vPNrWcBINdrNnlegml8nLUy0rlKztCQ/4pxW8w==", - "license": "MIT", - "dependencies": { - "@rdfjs/sink": "^2.0.1", - "jsonld": "^8.3.3", - "readable-stream": "^4.7.0", - "stream-chunks": "^1.0.0" - } - }, "node_modules/@rdfjs/serializer-ntriples": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@rdfjs/serializer-ntriples/-/serializer-ntriples-2.0.1.tgz", @@ -744,23 +609,6 @@ "readable-stream": "^4.5.2" } }, - "node_modules/@rdfjs/serializer-turtle": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@rdfjs/serializer-turtle/-/serializer-turtle-1.1.5.tgz", - "integrity": "sha512-uvIFUOuMuk8JrJnng/tWKIQ+8XI6YLEms75YdvZ49LtIyyfbDqKz76EybgnD/zZYfMhVVkguKtheBC9h08g1PQ==", - "license": "MIT", - "dependencies": { - "@rdfjs/data-model": "^2.0.1", - "@rdfjs/namespace": "^2.0.0", - "@rdfjs/prefix-map": "^0.1.1", - "@rdfjs/sink": "^2.0.0", - "@rdfjs/term-map": "^2.0.0", - "@rdfjs/to-ntriples": "^3.0.1", - "@rdfjs/tree": "^0.2.1", - "readable-stream": "^4.3.0", - "stream-chunks": "^1.0.0" - } - }, "node_modules/@rdfjs/sink": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@rdfjs/sink/-/sink-2.0.1.tgz", @@ -773,50 +621,12 @@ "integrity": "sha512-BwCTTsMN/tfQl6QzD2oHn9A08e4af+hlzAz/d5XXrlOkYMEDUAqFuh2Odj9EbayhAEeN4wA743Mj2yC0/s69rg==", "license": "MIT" }, - "node_modules/@rdfjs/term-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@rdfjs/term-map/-/term-map-2.0.2.tgz", - "integrity": "sha512-EJ2FmmdEUsSR/tU1nrizRLWzH24YzhuvesrbUWxC3Fs0ilYNdtTbg0RaFJDUnJF3HkbNBQe8Zrt/uvU/hcKnHg==", - "license": "MIT", - "dependencies": { - "@rdfjs/to-ntriples": "^3.0.1" - } - }, - "node_modules/@rdfjs/term-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@rdfjs/term-set/-/term-set-2.0.3.tgz", - "integrity": "sha512-DyXrKWEx+mtAFUZVU7bc3Va6/KZ8PsIp0RVdyWT9jfDgI/HCvNisZaBtAcm+SYTC45o+7WLkbudkk1bfaKVB0A==", - "license": "MIT", - "dependencies": { - "@rdfjs/to-ntriples": "^3.0.1" - } - }, "node_modules/@rdfjs/to-ntriples": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@rdfjs/to-ntriples/-/to-ntriples-3.0.1.tgz", "integrity": "sha512-gjoPAvh4j7AbGMjcDn/8R4cW+d/FPtbfbMM0uQXkyfBFtNUW2iVgrqsgJ65roLc54Y9A2TTFaeeTGSvY9a0HCQ==", "license": "MIT" }, - "node_modules/@rdfjs/traverser": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@rdfjs/traverser/-/traverser-0.1.4.tgz", - "integrity": "sha512-53QYlxiQIxH8k4jutjet1EjdZfyKCDSsfqnj2YejAJ1X8mLDMSOsneMM5savBwBR0ROfAhKVtZVb+pego+JLiw==", - "license": "MIT", - "dependencies": { - "@rdfjs/to-ntriples": "^3.0.1" - } - }, - "node_modules/@rdfjs/tree": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@rdfjs/tree/-/tree-0.2.1.tgz", - "integrity": "sha512-J70CQ7R8Ivfs1FFUxtFN7ADb5wTMgbhn0O558NXSXQHItmSavT6cXmQlIokbmboU+grhu56iR/8Bl9do8LCq+w==", - "license": "MIT", - "dependencies": { - "@rdfjs/namespace": "^2.0.0", - "@rdfjs/term-map": "^2.0.0", - "@rdfjs/term-set": "^2.0.1" - } - }, "node_modules/@rdfjs/types": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@rdfjs/types/-/types-2.0.1.tgz", @@ -1771,17 +1581,6 @@ "node": "^12.20 || >= 14.13" } }, - "node_modules/file-fetch": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/file-fetch/-/file-fetch-2.0.1.tgz", - "integrity": "sha512-jN4OveNyFdDIscQgaKL3vpPN5i4WnoQdWs1VQgT+3+SxsOW4+mQQzgOPQa4BjbKSkjeMv4xi+wLAMUKcL3CFtg==", - "license": "MIT", - "dependencies": { - "mime-types": "^3.0.1", - "readable-stream": "^4.4.2", - "stream-chunks": "^1.0.0" - } - }, "node_modules/follow-redirects": { "version": "1.15.9", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", @@ -1899,16 +1698,6 @@ "dev": true, "license": "ISC" }, - "node_modules/grapoi": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/grapoi/-/grapoi-1.1.3.tgz", - "integrity": "sha512-3Qi6hJG6P+m6YhOkpe2N60z0a7/nHW7FCcx1PqzBMydpsoQ0gerba5hLTnN4bDz+5rLtIK0LbBQzWdYLBQ39ug==", - "license": "MIT", - "dependencies": { - "@rdfjs/namespace": "^2.0.0", - "@rdfjs/term-set": "^2.0.0" - } - }, "node_modules/happy-dom": { "version": "17.4.4", "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.4.4.tgz", @@ -2119,21 +1908,6 @@ "node": ">=12.0.0" } }, - "node_modules/jsonld": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-8.3.3.tgz", - "integrity": "sha512-9YcilrF+dLfg9NTEof/mJLMtbdX1RJ8dbWtJgE00cMOIohb1lIyJl710vFiTaiHTl6ZYODJuBd32xFvUhmv3kg==", - "license": "BSD-3-Clause", - "dependencies": { - "@digitalbazaar/http-client": "^3.4.1", - "canonicalize": "^1.0.1", - "lru-cache": "^6.0.0", - "rdf-canonize": "^3.4.0" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/jsonld-context-parser": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/jsonld-context-parser/-/jsonld-context-parser-3.0.0.tgz", @@ -2185,18 +1959,6 @@ "url": "https://github.com/sponsors/rubensworks/" } }, - "node_modules/jsonld/node_modules/rdf-canonize": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-3.4.0.tgz", - "integrity": "sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==", - "license": "BSD-3-Clause", - "dependencies": { - "setimmediate": "^1.0.5" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", @@ -2207,43 +1969,6 @@ "graceful-fs": "^4.1.9" } }, - "node_modules/ky": { - "version": "0.33.3", - "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz", - "integrity": "sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==", - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/ky?sponsor=1" - } - }, - "node_modules/ky-universal": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.11.0.tgz", - "integrity": "sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==", - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "node-fetch": "^3.2.10" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/ky-universal?sponsor=1" - }, - "peerDependencies": { - "ky": ">=0.31.4", - "web-streams-polyfill": ">=3.2.1" - }, - "peerDependenciesMeta": { - "web-streams-polyfill": { - "optional": true - } - } - }, "node_modules/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", @@ -2267,18 +1992,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/magic-string": { "version": "0.30.17", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", @@ -2361,27 +2074,6 @@ "node": ">=4" } }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -2413,13 +2105,12 @@ "license": "MIT" }, "node_modules/n3": { - "version": "1.24.2", - "resolved": "https://registry.npmjs.org/n3/-/n3-1.24.2.tgz", - "integrity": "sha512-j/3PKmK0MA3tAohDCl9y1JDaNxp8wCnhTtrOOgZ1O17JVtWLkzHsp2jZ8YhY2uS4FWQAm6mExcXvl7C8lwXyaw==", + "version": "1.25.2", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.25.2.tgz", + "integrity": "sha512-ZBPnAgOw4sze/hnyoydNA5Ts9wbwiG+BXssTkdBKD6IkQZcg1IfQdo5AMU9JhsIu/RGtRD1QD0gphEhk/6ZnWA==", "license": "MIT", "dependencies": { "buffer": "^6.0.3", - "queue-microtask": "^1.1.2", "readable-stream": "^4.0.0" }, "engines": { @@ -2593,12 +2284,6 @@ "node": ">= 0.6.0" } }, - "node_modules/proto-fetch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/proto-fetch/-/proto-fetch-2.0.0.tgz", - "integrity": "sha512-QuhQVYN9WxCbJmfp/s3HLofEaDr/Jkq873++mo126XB2h+TFcKIGCIxeORH5ww9MOi2uP1SfWy4EgQH5PuBfdQ==", - "license": "MIT" - }, "node_modules/punycode.js": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", @@ -2625,38 +2310,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/rdf-canonize": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-4.0.1.tgz", - "integrity": "sha512-B5ynHt4sasbUafzrvYI2GFARgeFcD8Sx9yXPbg7gEyT2EH76rlCv84kyO6tnxzVbxUN/uJDbK1S/MXh+DsnuTA==", - "license": "BSD-3-Clause", - "dependencies": { - "setimmediate": "^1.0.5" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/rdf-data-factory": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-2.0.2.tgz", @@ -2670,33 +2323,6 @@ "url": "https://github.com/sponsors/rubensworks/" } }, - "node_modules/rdf-ext": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/rdf-ext/-/rdf-ext-2.5.2.tgz", - "integrity": "sha512-xndLCbnxcPUZ2CxdQX/BdHjAUsZuFuA4Uw2ddDZnX3vhLKoTIaXunWyp1r9yfX66Nxv0mEkzm71YIi19ex/pEg==", - "license": "MIT", - "dependencies": { - "@rdfjs/data-model": "^2.0.1", - "@rdfjs/dataset": "^2.0.1", - "@rdfjs/environment": "^1.0.0", - "@rdfjs/fetch-lite": "^3.2.1", - "@rdfjs/formats": "^4.0.0", - "@rdfjs/io": "^1.0.0", - "@rdfjs/namespace": "^2.0.0", - "@rdfjs/normalize": "^2.0.0", - "@rdfjs/prefix-map": "^0.1.1", - "@rdfjs/score": "^0.1.1", - "@rdfjs/term-map": "^2.0.0", - "@rdfjs/term-set": "^2.0.1", - "@rdfjs/to-ntriples": "^3.0.1", - "@rdfjs/traverser": "^0.1.1", - "file-fetch": "^2.0.0", - "grapoi": "^1.0.2", - "nodeify-fetch": "^3.1.0", - "proto-fetch": "^2.0.0", - "readable-stream": "^4.3.0" - } - }, "node_modules/rdfxml-streaming-parser": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/rdfxml-streaming-parser/-/rdfxml-streaming-parser-2.4.0.tgz", @@ -2840,12 +2466,6 @@ "dev": true, "license": "MIT" }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "license": "MIT" - }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -3076,18 +2696,6 @@ "dev": true, "license": "MIT" }, - "node_modules/undici": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", - "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", - "license": "MIT", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -3355,12 +2963,6 @@ "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "dev": true, "license": "Apache-2.0" - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" } } } diff --git a/package.json b/package.json index 603b5b2..fdae6c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "shacl-tulip", - "version": "0.0.2", + "version": "0.0.3", "type": "module", "main": "./src/index.js", "module": "./src/index.js", @@ -24,6 +24,6 @@ "dependencies": { "@rdfjs/fetch-lite": "^3.3.0", "@rdfjs/formats-common": "^3.1.0", - "rdf-ext": "^2.5.2" + "n3": "^1.25.2" } } diff --git a/src/classes/ClassDataset.js b/src/classes/ClassDataset.js index 2368abc..81416a9 100644 --- a/src/classes/ClassDataset.js +++ b/src/classes/ClassDataset.js @@ -15,8 +15,8 @@ export class ClassDataset extends RdfDataset { if (quad.predicate.value === RDFS.subClassOf.value && quad.subject.termType !== 'BlankNode' && quad.object.termType !== 'BlankNode' ) { - this.addQuad(quad) - this.dispatchEvent(new CustomEvent('quad', { detail: quad })); + this.addQuad(quad) + this.dispatchEvent(new CustomEvent('quad', { detail: quad })); } } } \ No newline at end of file diff --git a/src/classes/FormBase.js b/src/classes/FormBase.js index a3da488..85c4e47 100644 --- a/src/classes/FormBase.js +++ b/src/classes/FormBase.js @@ -2,9 +2,10 @@ * */ -import rdf from 'rdf-ext'; import { RDF } from '../modules/namespaces'; import { isEmptyObject, toIRI} from '../modules/utils'; +import { DataFactory } from 'n3'; +const { namedNode, blankNode, quad } = DataFactory; export class FormBase { @@ -140,7 +141,7 @@ export class FormBase { // Identify the record's subject (named or blank node) var subject = this._getRecordSubjectTerm(subject_uri, this.content[class_uri][subject_uri]) // Add the triple stating the subject is of type class - let firstQuad = rdf.quad(subject, rdf.namedNode(RDF.type.value), rdf.namedNode(class_uri)) + let firstQuad = quad(subject, namedNode(RDF.type.value), namedNode(class_uri)) quadArray.push(firstQuad) // Now we need to add all triples relating to the properties of the record. for (var triple_predicate of Object.keys(this.content[class_uri][subject_uri])) { @@ -161,7 +162,7 @@ export class FormBase { continue } // now set the predicate as a named node - var predicate = rdf.namedNode(triple_predicate) + var predicate = namedNode(triple_predicate) // In order to set the node type of the object, we first need to figure it out var [nodeFunc, dt] = shapesDS.getPropertyNodeKind(class_uri, triple_predicate, this.ID_IRI) // Now we can create the object nodes for each property @@ -169,13 +170,13 @@ export class FormBase { // val: all values of a given property of an identifiable object let triple_object if (dt) { - triple_object = nodeFunc(val, rdf.namedNode(dt)) + triple_object = nodeFunc(val, namedNode(dt)) } else { triple_object = nodeFunc(val) } // and finally we can add the quads to the store - let quad = rdf.quad(subject, predicate, triple_object) - quadArray.push(quad) + let q = quad(subject, predicate, triple_object) + quadArray.push(q) } } return quadArray @@ -202,9 +203,9 @@ export class FormBase { var subject if (Object.keys(record).indexOf(this.ID_IRI) >= 0) { var subject_iri = record[this.ID_IRI][0] - subject = rdf.namedNode(subject_iri) + subject = namedNode(subject_iri) } else { - subject = rdf.blankNode(record_id) + subject = blankNode(record_id) } return subject } @@ -258,7 +259,7 @@ export class FormBase { if (this.content[class_uri]) { // If we are in edit mode, the first step is to delete existing quads from graphData if (editMode) { - RdfDS.data.graph.deleteMatches(rdf.namedNode(node_uri), null, null, null) + RdfDS.data.graph.deleteMatches(namedNode(node_uri), null, null, null) } // Then we generate the quads @@ -285,9 +286,9 @@ export class FormBase { // - for each triple in oldTriples: create a new one with same subject and predicate // and with new IRI as object, then delete the old triple if (editMode && subject_iri !== null && subject_iri !== node_uri) { - var objectQuads = RdfDS.getObjectTriples(rdf.namedNode(node_uri)) + var objectQuads = RdfDS.getObjectTriples(namedNode(node_uri)) objectQuads.forEach((quad) => { - let new_quad = rdf.quad(quad.subject, quad.predicate, subject) + let new_quad = quad(quad.subject, quad.predicate, subject) RdfDS.data.graph.delete(quad) RdfDS.data.graph.add(new_quad) }); diff --git a/src/classes/RdfDataset.js b/src/classes/RdfDataset.js index add00a9..14731db 100644 --- a/src/classes/RdfDataset.js +++ b/src/classes/RdfDataset.js @@ -1,8 +1,8 @@ -import rdf from 'rdf-ext'; import { readRDF } from '../modules/io' import { RDF, XSD } from '../modules/namespaces'; import { toCURIE } from '../modules/utils'; -import formatsPretty from '@rdfjs/formats/pretty.js' +import { Store, Writer, DataFactory } from 'n3'; +const { namedNode, literal } = DataFactory; /** * A class wrapping an RDF dataset (quad-store) from the `rdf-ext` library. @@ -13,8 +13,6 @@ export class RdfDataset { */ constructor(data = {}) { this.data = data; - this.rdfPretty = rdf.clone(); - this.rdfPretty.formats.import(formatsPretty); this.data.prefixes = {}; this.data.serializedGraph = ''; this.data.graphLoaded = false; @@ -37,11 +35,11 @@ export class RdfDataset { /** * Create a quad store compliant with the [RDF/JS dataset specification](https://rdf.js.org/dataset-spec/) - * via the `rdf-ext` package - * @returns {import("rdf-ext").DatasetCore} The RDF dataset instance. + * via the `n3` package + * @returns {} The RDF dataset instance. */ createDataset() { - return rdf.dataset() + return new Store(); } /** * Loads RDF data from a given URL and processes prefixes and quads. @@ -60,16 +58,14 @@ export class RdfDataset { // Load prefixes quadStream.on('prefix', (prefix, ns) => { this.onPrefixFn(prefix, ns) + }).on('data', quad => { + this.onDataFn(quad) }).on('end', () => { + this.onDataEndFn() this.onPrefixEndFn() - }) - // Load data - quadStream.on('data', quad => { - this.onDataFn(quad) - }).on('end', async () => { - await this.onDataEndFn() + }).on('error', err => { + console.error('Error while processing quadStream:', err); }); - return result } @@ -83,7 +79,7 @@ export class RdfDataset { /** * Process an RDF prefix. * @param {string} prefix - The prefix string. - * @param {import("rdf-ext").NamedNode} ns - The namespace associated with the prefix. + * @param {} ns - The namespace associated with the prefix. */ onPrefixFn(prefix, ns) { this.data.prefixes[prefix] = ns.value; @@ -96,29 +92,29 @@ export class RdfDataset { /** * Process an RDF quad - * @param {import("rdf-ext").Quad} quad - The RDF quad. + * @param {} quad - The RDF quad. */ onDataFn(quad) { // The first following line, moved here from shacl-vue's graphdata composable, // was an attempt to solve https://hub.datalad.org/datalink/annotate-trr379-demo/issues/32. // But it was a faulty attempt, since the object was different. Still, leaving it here since // deleting matches would prospectively solve the duplication of named node or literal objects - this.data.graph.deleteMatches(quad.subject, quad.predicate, quad.object, null) + // this.data.graph.removeMatches(quad.subject, quad.predicate, quad.object, null) this.addQuad(quad) this.dispatchEvent(new CustomEvent('quad', { detail: quad })); } - async onDataEndFn() { - await this.updateSerializedGraph() + + onDataEndFn() { this.data.graphLoaded = true this.dispatchEvent(new CustomEvent('graphLoaded', { detail: this.data.graph })); } /** * Add an RDF quad to the dataset - * @param {import("rdf-ext").Quad} quad - The RDF quad to add. + * @param {} quad - The RDF quad to add. */ addQuad(quad) { - this.data.graph.add(quad) + this.data.graph.addQuad(quad) } /** @@ -126,33 +122,35 @@ export class RdfDataset { * @returns {Promise} The serialized RDF graph in Turtle format. */ async serializeGraph() { - return (await this.rdfPretty.io.dataset.toText('text/turtle', this.data.graph)).trim() - } - - async updateSerializedGraph() { - this.data.serializedGraph = (await this.rdfPretty.io.dataset.toText('text/turtle', this.data.graph)).trim() + // Using N3.Writer to serialize graph to Turtle + return new Promise((resolve, reject) => { + const writer = new Writer({ prefixes: this.data.prefixes }); + writer.addQuads(this.data.graph.getQuads(null, null, null, null)); + writer.end((error, result) => { + if (error) reject(error); + else resolve(result.trim()); + }); + }); } /** * Checks if a given RDF node represents an RDF list. - * @param {import("rdf-ext").Term} node - The RDF node to check. + * @param {} node - The RDF node to check. * @returns {boolean} True if the node represents an RDF list, otherwise false. */ isRdfList(node) { let hasFirst = false; let hasRest = false; - this.data.graph.forEach((quad) => { - if (quad.subject.equals(node)) { - if (quad.predicate.value === RDF.first.value) hasFirst = true; - if (quad.predicate.value === RDF.rest.value) hasRest = true; - } + this.data.graph.getQuads(node, null, null, null).forEach((quad) => { + if (quad.predicate.value === RDF.first.value) hasFirst = true; + if (quad.predicate.value === RDF.rest.value) hasRest = true; }); return hasFirst && hasRest; }; /** * Converts an RDF list to an array. - * @param {import("rdf-ext").Term} startNode - The starting node of the RDF list. + * @param {} startNode - The starting node of the RDF list. * @returns {Array} The converted RDF list as an array. */ rdfListToArray(startNode) { @@ -161,53 +159,38 @@ export class RdfDataset { while (currentNode && currentNode.value !== RDF.nil.value) { let listItem = null; // Get the first element in the RDF list - this.data.graph.forEach((quad) => { - if (quad.subject.equals(currentNode) && quad.predicate.value === RDF.first.value) { - // Resolve blank nodes recursively, but handle literals and IRIs separately - if (quad.object.termType === "BlankNode") { - listItem = this.resolveBlankNode(quad.object, this.data.graph); - } else if (quad.object.termType === "Literal") { - listItem = quad.object.value; // Store literal value - } else if (quad.object.termType === "NamedNode") { - listItem = quad.object.value; // Store IRI as a string + this.data.graph.getQuads(currentNode, RDF.first, null, null).forEach(quad => { + if (quad.object.termType === 'BlankNode') { + if (this.isRdfList(quad.object)) { + listItem = this.rdfListToArray(quad.object); + } else { + listItem = this.resolveBlankNode(quad.object); } + } else if (quad.object.termType === 'Literal' || quad.object.termType === 'NamedNode') { + listItem = quad.object.value; } }); if (listItem !== null) { listItems.push(listItem); } // Move to the next item in the list (rdf:rest) - let nextNode = null; - this.data.graph.forEach((quad) => { - if (quad.subject.equals(currentNode) && quad.predicate.value === RDF.rest.value) { - nextNode = quad.object; - } - }); - currentNode = nextNode; + const restQuads = this.data.graph.getQuads(currentNode, RDF.rest, null, null); + currentNode = restQuads.length > 0 ? restQuads[0].object : null; } return listItems; }; resolveBlankNode(blankNode) { let resolvedObject = {}; - this.data.graph.forEach((quad) => { - if (quad.subject.equals(blankNode)) { - const predicate = quad.predicate.value; - const object = quad.object; - - // If the object is a blank node, resolve it recursively - if (object.termType === "BlankNode") { - // Check if it's an RDF list and convert it to an array - if (this.isRdfList(object)) { - resolvedObject[predicate] = this.rdfListToArray(object); - } else { - resolvedObject[predicate] = this.resolveBlankNode(object); - } - } else if (object.termType === "Literal") { - resolvedObject[predicate] = object.value; // Handle literal values - } else if (object.termType === "NamedNode") { - resolvedObject[predicate] = object.value; // Handle IRIs as strings + this.data.graph.getQuads(blankNode, null, null, null).forEach(({ predicate, object }) => { + if (object.termType === 'BlankNode') { + if (this.isRdfList(object)) { + resolvedObject[predicate.value] = this.rdfListToArray(object); + } else { + resolvedObject[predicate.value] = this.resolveBlankNode(object); } + } else if (object.termType === 'Literal' || object.termType === 'NamedNode') { + resolvedObject[predicate.value] = object.value; } }); return resolvedObject; @@ -215,25 +198,16 @@ export class RdfDataset { getLiteralAndNamedNodes(predicate, propertyClass, prefixes) { var propClassCurie = toCURIE(propertyClass, prefixes) - // a) use the literal node with xsd data type - const literalNodes = rdf.grapoi({ dataset: this.data.graph }) - .hasOut(predicate, rdf.literal(String(propClassCurie), XSD.anyURI)) - .quads(); - // b) and the named node - const uriNodes = rdf.grapoi({ dataset: this.data.graph }) - .hasOut(predicate, rdf.namedNode(propertyClass)) - .quads(); - // return as a concatenated array of quads - return Array.from(literalNodes).concat(Array.from(uriNodes)) + const literalQuads = this.data.graph.getQuads(null, predicate, literal(String(propClassCurie), XSD.anyURI), null) + const uriQuads = this.data.graph.getQuads(null, predicate, namedNode(propertyClass), null) + return literalQuads.concat(uriQuads) } getSubjectTriples(someTerm) { - const quads = rdf.grapoi({ dataset: this.data.graph, term: someTerm }).out().quads(); - return Array.from(quads) + return this.data.graph.getQuads(someTerm, null, null, null); } getObjectTriples(someTerm) { - const quads = rdf.grapoi({ dataset: this.data.graph, term: someTerm }).in().quads(); - return Array.from(quads) + return this.data.graph.getQuads(null, null, someTerm, null); } } diff --git a/src/classes/ShapesDataset.js b/src/classes/ShapesDataset.js index ce23670..629c2e3 100644 --- a/src/classes/ShapesDataset.js +++ b/src/classes/ShapesDataset.js @@ -4,7 +4,8 @@ import { RdfDataset } from './RdfDataset' import { SHACL, RDF } from '../modules/namespaces'; -import rdf from 'rdf-ext'; +import { DataFactory } from 'n3'; +const { namedNode, literal, blankNode } = DataFactory; import { toIRI} from '../modules/utils'; export class ShapesDataset extends RdfDataset { @@ -102,17 +103,17 @@ export class ShapesDataset extends RdfDataset { // if sh:nodeKind == sh:Literal if (propertyShape[SHACL.nodeKind.value] == SHACL.Literal.value) { // sh:nodeKind == sh:Literal - nodeFunc = rdf.literal + nodeFunc = literal // sh:datatype exists if (propertyShape.hasOwnProperty(SHACL.datatype.value)) { dt = propertyShape[SHACL.datatype.value] } } else if (propertyShape[SHACL.nodeKind.value] == SHACL.IRI.value) { // sh:nodeKind == sh:IRI - nodeFunc = rdf.namedNode + nodeFunc = namedNode } else if (propertyShape[SHACL.nodeKind.value] == SHACL.BlankNode.value) { // sh:nodeKind == sh:BlankNode - nodeFunc = rdf.blankNode + nodeFunc = blankNode } else if (propertyShape[SHACL.nodeKind.value] == SHACL.BlankNodeOrIRI.value) { // sh:nodeKind == sh:BlankNodeOrIRI // If the same property shape has a sh:class field, and if that class @@ -128,26 +129,26 @@ export class ShapesDataset extends RdfDataset { var associatedNodeShape = this.data.nodeShapes[toIRI(shClass, this.data.prefixes)] var hasIdField = associatedNodeShape.properties.find((prop) => prop[SHACL.path.value] == id_uri) if (hasIdField) { - nodeFunc = rdf.namedNode + nodeFunc = namedNode } else { - nodeFunc = rdf.blankNode + nodeFunc = blankNode } } else { - nodeFunc = rdf.namedNode + nodeFunc = namedNode } } else { console.error(`\t- NodeKind not supported: ${propertyShape[SHACL.nodeKind.value]}\n\t\tAdding triple with literal object to graphData`) - nodeFunc = rdf.literal + nodeFunc = literal } } else if (propertyShape.hasOwnProperty(SHACL.in.value)) { // This is a temporary workaround; should definitely not be permanent // Assume Literal nodekind for any arrays console.log(`\t- NodeKind not found for property shape: ${property_uri}; found 'sh:in'. Setting to default literal`) - nodeFunc = rdf.literal + nodeFunc = literal } else { console.log(`\t- NodeKind not found for property shape: ${property_uri}. Setting to default literal`) - nodeFunc = rdf.literal + nodeFunc = literal } return [nodeFunc, dt] } diff --git a/src/index.js b/src/index.js index 3fa178e..ab496bf 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,7 @@ export { ClassDataset } from './classes/ClassDataset'; export { FormBase } from './classes/FormBase'; export { RdfDataset } from './classes/RdfDataset'; export { ShapesDataset } from './classes/ShapesDataset'; +export { namespace } from "./modules/namespaces.js"; export * from "./modules/io.js"; export * from "./modules/namespaces.js"; diff --git a/src/modules/io.js b/src/modules/io.js index 4b786ab..e3d3af8 100644 --- a/src/modules/io.js +++ b/src/modules/io.js @@ -9,8 +9,6 @@ import formats from '@rdfjs/formats-common' import fetch from '@rdfjs/fetch-lite' -import formatsPretty from '@rdfjs/formats/pretty.js' -import rdf from 'rdf-ext' export async function readRDF(file_url, headers = { "Content-Type": "text/turtle" }) { const url = file_url; diff --git a/src/modules/namespaces.js b/src/modules/namespaces.js index af168ad..1c3d8b4 100644 --- a/src/modules/namespaces.js +++ b/src/modules/namespaces.js @@ -4,9 +4,20 @@ */ -import rdf from 'rdf-ext'; -export const SHACL = rdf.namespace('http://www.w3.org/ns/shacl#'); -export const RDF = rdf.namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#'); -export const DASH = rdf.namespace('http://datashapes.org/dash#'); -export const RDFS = rdf.namespace('http://www.w3.org/2000/01/rdf-schema#'); -export const XSD = rdf.namespace('http://www.w3.org/2001/XMLSchema#'); \ No newline at end of file +import { DataFactory } from 'n3'; +const { namedNode } = DataFactory; + +export function namespace(baseIRI) { + return new Proxy({}, { + get(_, prop) { + // Return a NamedNode for every accessed property + return namedNode(baseIRI + prop); + } + }); +} + +export const SHACL = namespace('http://www.w3.org/ns/shacl#'); +export const RDF = namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#'); +export const DASH = namespace('http://datashapes.org/dash#'); +export const RDFS = namespace('http://www.w3.org/2000/01/rdf-schema#'); +export const XSD = namespace('http://www.w3.org/2001/XMLSchema#'); \ No newline at end of file diff --git a/tests/ClassDataset.test.js b/tests/ClassDataset.test.js index fe0bc86..d12d562 100644 --- a/tests/ClassDataset.test.js +++ b/tests/ClassDataset.test.js @@ -33,11 +33,11 @@ describe('ClassDataset', () => { expect(dataset.data.graphLoaded).toBe(true); expect(dataset.data.prefixesLoaded).toBe(true); const serializedGraph = await dataset.serializeGraph(); - expect(serializedGraph).not.toContain(''); - expect(serializedGraph).not.toContain(''); - expect(serializedGraph).not.toContain('"example"'); - expect(serializedGraph).toContain(''); - expect(serializedGraph).toContain(''); + expect(serializedGraph).not.toContain('ex:subject'); + expect(serializedGraph).not.toContain('ex:predicate'); + expect(serializedGraph).not.toContain('"Test value"'); + expect(serializedGraph).toContain('dlthings:Property'); + expect(serializedGraph).toContain('dlthings:Thing'); }); }); diff --git a/tests/FormBase.test.js b/tests/FormBase.test.js index 42009dc..cc34456 100644 --- a/tests/FormBase.test.js +++ b/tests/FormBase.test.js @@ -3,8 +3,9 @@ import { FormBase } from '@/classes/FormBase'; import { ShapesDataset } from '@/classes/ShapesDataset'; import { RdfDataset } from '@/classes/RdfDataset'; import { RDF } from '@/modules/namespaces' -import rdf from 'rdf-ext' import httpServer from 'http-server'; +import { DataFactory } from 'n3'; +const { namedNode } = DataFactory; let server; const PORT = 8083; const HOST = 'localhost'; @@ -82,7 +83,7 @@ describe('FormBase', () => { it('should convert an RDF dataset correctly to form content, and save it back', () => { let class_uri = 'https://concepts.datalad.org/s/social/unreleased/Person' let subject_uri = 'http://example.com/testPerson' - let subject_term = rdf.namedNode(subject_uri) + let subject_term = namedNode(subject_uri) let predicate_uri = 'https://concepts.datalad.org/s/social/unreleased/given_name' form.quadsToFormData(class_uri, subject_term, rdfDS) expect(Object.keys(form.content)).toContain(class_uri) diff --git a/tests/RdfDataset.test.js b/tests/RdfDataset.test.js index 511e8a7..63cc528 100644 --- a/tests/RdfDataset.test.js +++ b/tests/RdfDataset.test.js @@ -1,9 +1,9 @@ import { describe, it, expect, beforeEach, vi} from 'vitest'; -import rdf from 'rdf-ext'; +import { DataFactory } from 'n3'; import { RDF, XSD } from '@/modules/namespaces'; import { RdfDataset } from '@/classes/RdfDataset'; import httpServer from 'http-server'; - +const { namedNode, literal, blankNode, quad } = DataFactory; let server; const PORT = 8080; const HOST = 'localhost'; @@ -25,27 +25,27 @@ describe('RdfDataset', () => { it('should add a quad to the dataset', () => { console.log(`Running RdfDataset Test ${i++}...`) - const subject = rdf.namedNode('http://example.com/subject'); - const predicate = rdf.namedNode('http://example.com/predicate'); - const object = rdf.literal('example', XSD.string); - const quad = rdf.quad(subject, predicate, object); + const subject = namedNode('http://example.com/subject'); + const predicate = namedNode('http://example.com/predicate'); + const object = literal('example', XSD.string); + const q = quad(subject, predicate, object); - dataset.addQuad(quad); + dataset.addQuad(q); expect(dataset.data.graph.size).toBe(1); - expect(dataset.data.graph.has(quad)).toBe(true); + expect(dataset.data.graph.has(q)).toBe(true); }); it('should correctly detect an RDF list', () => { console.log(`Running RdfDataset Test ${i++}...`) - const node1 = rdf.blankNode(); - const node2 = rdf.blankNode(); - const node3 = rdf.namedNode(RDF.nil.value); + const node1 = blankNode(); + const node2 = blankNode(); + const node3 = namedNode(RDF.nil.value); - dataset.addQuad(rdf.quad(node1, RDF.first, rdf.literal("Item 1"))); - dataset.addQuad(rdf.quad(node1, RDF.rest, node2)); - dataset.addQuad(rdf.quad(node2, RDF.first, rdf.literal("Item 2"))); - dataset.addQuad(rdf.quad(node2, RDF.rest, node3)); + dataset.addQuad(quad(node1, RDF.first, literal("Item 1"))); + dataset.addQuad(quad(node1, RDF.rest, node2)); + dataset.addQuad(quad(node2, RDF.first, literal("Item 2"))); + dataset.addQuad(quad(node2, RDF.rest, node3)); expect(dataset.isRdfList(node1)).toBe(true); expect(dataset.isRdfList(node2)).toBe(true); @@ -54,14 +54,14 @@ describe('RdfDataset', () => { it('should convert an RDF list to an array', () => { console.log(`Running RdfDataset Test ${i++}...`) - const node1 = rdf.blankNode(); - const node2 = rdf.blankNode(); - const node3 = rdf.namedNode(RDF.nil.value); + const node1 = blankNode(); + const node2 = blankNode(); + const node3 = namedNode(RDF.nil.value); - dataset.addQuad(rdf.quad(node1, RDF.first, rdf.literal("Item 1"))); - dataset.addQuad(rdf.quad(node1, RDF.rest, node2)); - dataset.addQuad(rdf.quad(node2, RDF.first, rdf.literal("Item 2"))); - dataset.addQuad(rdf.quad(node2, RDF.rest, node3)); + dataset.addQuad(quad(node1, RDF.first, literal("Item 1"))); + dataset.addQuad(quad(node1, RDF.rest, node2)); + dataset.addQuad(quad(node2, RDF.first, literal("Item 2"))); + dataset.addQuad(quad(node2, RDF.rest, node3)); const result = dataset.rdfListToArray(node1); expect(result).toEqual(["Item 1", "Item 2"]); @@ -69,12 +69,12 @@ describe('RdfDataset', () => { it('should serialize the dataset to Turtle format', async () => { console.log(`Running RdfDataset Test ${i++}...`) - const subject = rdf.namedNode('http://example.com/subject'); - const predicate = rdf.namedNode('http://example.com/predicate'); - const object = rdf.literal('example', XSD.string); - const quad = rdf.quad(subject, predicate, object); + const subject = namedNode('http://example.com/subject'); + const predicate = namedNode('http://example.com/predicate'); + const object = literal('example', XSD.string); + const q = quad(subject, predicate, object); - dataset.addQuad(quad); + dataset.addQuad(q); const serializedGraph = await dataset.serializeGraph(); expect(serializedGraph).toContain(''); expect(serializedGraph).toContain(''); @@ -91,15 +91,31 @@ describe('RdfDataset', () => { expect(dataset.data.graphLoaded).toBe(false); expect(dataset.data.prefixesLoaded).toBe(false); const fileUrl = `http://${HOST}:${PORT}/tests/mockData.ttl` + // const graphLoadedHandler = vi.fn(); + // dataset.addEventListener('graphLoaded', graphLoadedHandler); + // await dataset.loadRDF(fileUrl); + // await new Promise(resolve => dataset.addEventListener('graphLoaded', resolve)); + + + // Add listener to await graph load const graphLoadedHandler = vi.fn(); - dataset.addEventListener('graphLoaded', graphLoadedHandler); - dataset.loadRDF(fileUrl); - await new Promise(resolve => dataset.addEventListener('graphLoaded', resolve)); + const graphLoadedPromise = new Promise(resolve => { + dataset.addEventListener('graphLoaded', event => { + graphLoadedHandler(event); + resolve(); + }); + }); + + await dataset.loadRDF(fileUrl); + await graphLoadedPromise; + + expect(graphLoadedHandler).toHaveBeenCalledTimes(1); - expect(dataset.data.graph.size).toBe(2); expect(dataset.data.prefixes['ex']).toBe('http://example.com/'); expect(dataset.data.graphLoaded).toBe(true); expect(dataset.data.prefixesLoaded).toBe(true); + expect(dataset.data.graph.size).toBe(2); + console.log('Quads in graph:', dataset.data.graph.getQuads(null, null, null, null)); console.log(`Closing server on http://${HOST}:${PORT}`); server.close(); @@ -110,30 +126,30 @@ describe('RdfDataset', () => { console.log(`Running RdfDataset Test ${i++}...`) const prefixHandler = vi.fn(); dataset.addEventListener('prefix', prefixHandler); - dataset.onPrefixFn('ex', rdf.namedNode('http://example.com/')); + dataset.onPrefixFn('ex', namedNode('http://example.com/')); expect(prefixHandler).toHaveBeenCalledTimes(1); expect(dataset.data.prefixes['ex']).toBe('http://example.com/'); }); it('should resolve blank nodes correctly', () => { console.log(`Running RdfDataset Test ${i++}...`) - const blankNode = rdf.blankNode(); - const predicate = rdf.namedNode('http://example.com/predicate'); - const object = rdf.literal('value'); + const bn = blankNode(); + const predicate = namedNode('http://example.com/predicate'); + const object = literal('value'); - dataset.addQuad(rdf.quad(blankNode, predicate, object)); + dataset.addQuad(quad(bn, predicate, object)); - const resolved = dataset.resolveBlankNode(blankNode); + const resolved = dataset.resolveBlankNode(bn); expect(resolved[predicate.value]).toBe('value'); }); it('should retrieve subject triples', () => { console.log(`Running RdfDataset Test ${i++}...`) - const subject = rdf.namedNode('http://example.com/subject'); - const predicate = rdf.namedNode('http://example.com/predicate'); - const object = rdf.literal('example'); + const subject = namedNode('http://example.com/subject'); + const predicate = namedNode('http://example.com/predicate'); + const object = literal('example'); - dataset.addQuad(rdf.quad(subject, predicate, object)); + dataset.addQuad(quad(subject, predicate, object)); const triples = dataset.getSubjectTriples(subject); expect(triples.length).toBe(1); @@ -142,11 +158,11 @@ describe('RdfDataset', () => { it('should retrieve object triples', () => { console.log(`Running RdfDataset Test ${i++}...`) - const subject = rdf.namedNode('http://example.com/subject'); - const predicate = rdf.namedNode('http://example.com/predicate'); - const object = rdf.literal('example'); + const subject = namedNode('http://example.com/subject'); + const predicate = namedNode('http://example.com/predicate'); + const object = literal('example'); - dataset.addQuad(rdf.quad(subject, predicate, object)); + dataset.addQuad(quad(subject, predicate, object)); const triples = dataset.getObjectTriples(object); expect(triples.length).toBe(1); diff --git a/tests/ShapesDataset.test.js b/tests/ShapesDataset.test.js index 9f6f2d7..edf6a18 100644 --- a/tests/ShapesDataset.test.js +++ b/tests/ShapesDataset.test.js @@ -1,6 +1,7 @@ import { describe, it, expect, beforeEach} from 'vitest'; import { ShapesDataset } from '@/classes/ShapesDataset'; -import rdf from 'rdf-ext' +import { DataFactory } from 'n3'; +const { literal, blankNode } = DataFactory; import httpServer from 'http-server'; let server; const PORT = 8082; @@ -84,14 +85,14 @@ describe('ShapesDataset', () => { ) expect(nk1[0]).toBeTypeOf('function') - expect(nk1[0]).toEqual(rdf.literal) + expect(nk1[0]).toEqual(literal) var nk2 = dataset.getPropertyNodeKind( 'https://concepts.datalad.org/s/social/unreleased/Person', 'https://concepts.datalad.org/s/things/v1/attributes', 'https://concepts.datalad.org/s/things/v1/id' ) expect(nk2[0]).toBeTypeOf('function') - expect(nk2[0]).toEqual(rdf.blankNode) + expect(nk2[0]).toEqual(blankNode) server.close(); });