diff --git a/.eslintrc b/.eslintrc index 4e247cb..00f1888 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,10 @@ { "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint", "prettier", "react"], + "plugins": [ + "@typescript-eslint", + "prettier", + "react" + ], "extends": [ "plugin:react/recommended", "plugin:@typescript-eslint/recommended", @@ -10,7 +14,9 @@ "parserOptions": { "ecmaVersion": 2018, "sourceType": "module", - "ecmaFeatures": { "jsx": true } + "ecmaFeatures": { + "jsx": true + } }, "settings": { "react": { diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b212b7a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "typescript.preferences.importModuleSpecifierEnding": "js", + "javascript.preferences.importModuleSpecifierEnding": "js" +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index cf01c33..5473fe3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17209,6 +17209,23 @@ "node": ">=12" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", + "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", @@ -20316,6 +20333,20 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", + "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { "version": "4.43.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.43.0.tgz", @@ -22395,18 +22426,17 @@ "license": "MIT" }, "node_modules/@testing-library/jest-dom": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", - "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.7.0.tgz", + "integrity": "sha512-RI2e97YZ7MRa+vxP4UUnMuMFL2buSsf0ollxUbTgrbPLKhMn8KVTx7raS6DYjC7v1NDVrioOvaShxsguLNISCA==", "dev": true, "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", - "chalk": "^3.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", - "lodash": "^4.17.21", + "picocolors": "^1.1.1", "redent": "^3.0.0" }, "engines": { @@ -23429,6 +23459,15 @@ "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", "license": "MIT" }, + "node_modules/@types/whatwg-mimetype": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz", + "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", @@ -25491,20 +25530,6 @@ "node": ">=12" } }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -29646,6 +29671,35 @@ "uglify-js": "^3.1.4" } }, + "node_modules/happy-dom": { + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-18.0.1.tgz", + "integrity": "sha512-qn+rKOW7KWpVTtgIUi6RVmTBZJSe2k0Db0vh1f7CWrWclkkc7/Q+FrOfkZIb2eiErLyqu5AXEzE7XthO9JVxRA==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.0.0", + "@types/whatwg-mimetype": "^3.0.2", + "whatwg-mimetype": "^3.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/happy-dom/node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -47124,126 +47178,1253 @@ }, "devDependencies": { "@rdfjs/types": "^1.0.1", - "@testing-library/react": "^14.1.2", - "start-server-and-test": "^2.0.3", - "ts-node": "^10.9.2" + "@testing-library/jest-dom": "^6.7.0", + "@testing-library/react": "^14.3.1", + "@testing-library/user-event": "^14.6.1", + "jsdom": "^26.1.0", + "vitest": "^3.2.4" } }, - "packages/react/node_modules/@rdfjs/types": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@rdfjs/types/-/types-1.1.2.tgz", - "integrity": "sha512-wqpOJK1QCbmsGNtyzYnojPU8gRDPid2JO0Q0kMtb4j65xhCK880cnKAfEOwC+dX85VJcCByQx5zOwyyfCjDJsg==", + "packages/react/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", + "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" } }, - "packages/react/node_modules/@testing-library/dom": { - "version": "9.3.4", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", - "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", + "packages/react/node_modules/@esbuild/android-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", + "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=14" + "node": ">=18" } }, - "packages/react/node_modules/@testing-library/react": { - "version": "14.3.1", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.3.1.tgz", - "integrity": "sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==", + "packages/react/node_modules/@esbuild/android-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", + "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^9.0.0", - "@types/react-dom": "^18.0.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "node": ">=18" } }, - "packages/react/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "packages/react/node_modules/@esbuild/android-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", + "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "deep-equal": "^2.0.5" + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "packages/react/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "packages/react/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", + "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=18" } }, - "packages/react/node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "packages/react/node_modules/@esbuild/darwin-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", + "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18" } }, - "packages/react/node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "packages/react/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", + "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", + "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/linux-arm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", + "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/linux-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", + "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/linux-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", + "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/linux-loong64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", + "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", + "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", + "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", + "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/linux-s390x": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", + "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/linux-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", + "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", + "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", + "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", + "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", + "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/sunos-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", + "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/win32-arm64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", + "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/win32-ia32": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", + "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@esbuild/win32-x64": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", + "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "packages/react/node_modules/@rdfjs/types": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rdfjs/types/-/types-1.1.2.tgz", + "integrity": "sha512-wqpOJK1QCbmsGNtyzYnojPU8gRDPid2JO0Q0kMtb4j65xhCK880cnKAfEOwC+dX85VJcCByQx5zOwyyfCjDJsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "packages/react/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", + "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "packages/react/node_modules/@rollup/rollup-android-arm64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", + "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "packages/react/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", + "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "packages/react/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", + "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "packages/react/node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", + "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "packages/react/node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", + "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", + "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", + "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", + "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", + "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", + "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", + "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", + "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", + "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", + "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", + "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "packages/react/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", + "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "packages/react/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", + "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "packages/react/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", + "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "packages/react/node_modules/@testing-library/dom": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", + "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.1.3", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=14" + } + }, + "packages/react/node_modules/@testing-library/react": { + "version": "14.3.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-14.3.1.tgz", + "integrity": "sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^9.0.0", + "@types/react-dom": "^18.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "packages/react/node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "packages/react/node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/react/node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "packages/react/node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/react/node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/react/node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/react/node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/react/node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/react/node_modules/aria-query": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", + "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "deep-equal": "^2.0.5" + } + }, + "packages/react/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "packages/react/node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "packages/react/node_modules/deep-equal": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", + "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "packages/react/node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT" + }, + "packages/react/node_modules/esbuild": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", + "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.9", + "@esbuild/android-arm": "0.25.9", + "@esbuild/android-arm64": "0.25.9", + "@esbuild/android-x64": "0.25.9", + "@esbuild/darwin-arm64": "0.25.9", + "@esbuild/darwin-x64": "0.25.9", + "@esbuild/freebsd-arm64": "0.25.9", + "@esbuild/freebsd-x64": "0.25.9", + "@esbuild/linux-arm": "0.25.9", + "@esbuild/linux-arm64": "0.25.9", + "@esbuild/linux-ia32": "0.25.9", + "@esbuild/linux-loong64": "0.25.9", + "@esbuild/linux-mips64el": "0.25.9", + "@esbuild/linux-ppc64": "0.25.9", + "@esbuild/linux-riscv64": "0.25.9", + "@esbuild/linux-s390x": "0.25.9", + "@esbuild/linux-x64": "0.25.9", + "@esbuild/netbsd-arm64": "0.25.9", + "@esbuild/netbsd-x64": "0.25.9", + "@esbuild/openbsd-arm64": "0.25.9", + "@esbuild/openbsd-x64": "0.25.9", + "@esbuild/openharmony-arm64": "0.25.9", + "@esbuild/sunos-x64": "0.25.9", + "@esbuild/win32-arm64": "0.25.9", + "@esbuild/win32-ia32": "0.25.9", + "@esbuild/win32-x64": "0.25.9" + } + }, + "packages/react/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "packages/react/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "packages/react/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "packages/react/node_modules/rollup": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", + "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.46.2", + "@rollup/rollup-android-arm64": "4.46.2", + "@rollup/rollup-darwin-arm64": "4.46.2", + "@rollup/rollup-darwin-x64": "4.46.2", + "@rollup/rollup-freebsd-arm64": "4.46.2", + "@rollup/rollup-freebsd-x64": "4.46.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", + "@rollup/rollup-linux-arm-musleabihf": "4.46.2", + "@rollup/rollup-linux-arm64-gnu": "4.46.2", + "@rollup/rollup-linux-arm64-musl": "4.46.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", + "@rollup/rollup-linux-ppc64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-musl": "4.46.2", + "@rollup/rollup-linux-s390x-gnu": "4.46.2", + "@rollup/rollup-linux-x64-gnu": "4.46.2", + "@rollup/rollup-linux-x64-musl": "4.46.2", + "@rollup/rollup-win32-arm64-msvc": "4.46.2", + "@rollup/rollup-win32-ia32-msvc": "4.46.2", + "@rollup/rollup-win32-x64-msvc": "4.46.2", + "fsevents": "~2.3.2" + } + }, + "packages/react/node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "packages/react/node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "packages/react/node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@vitest/pretty-format": "^3.2.4", + "@vitest/runner": "3.2.4", + "@vitest/snapshot": "3.2.4", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.2.4", + "@vitest/ui": "3.2.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } }, "packages/schema-converter-shex": { "name": "@ldo/schema-converter-shex", diff --git a/packages/connected/test/mocks/MockConnectedLdoDataset.ts b/packages/connected/test/mocks/MockConnectedLdoDataset.ts new file mode 100644 index 0000000..d17f2d7 --- /dev/null +++ b/packages/connected/test/mocks/MockConnectedLdoDataset.ts @@ -0,0 +1,13 @@ +import { ConnectedLdoDataset } from "@ldo/connected"; +import { createDatasetFactory } from "@ldo/dataset"; +import { createTransactionDatasetFactory } from "@ldo/subscribable-dataset"; +import { mockConnectedPlugin } from "./MockConnectedPlugin.js"; + +export function createMockConnectedLdoDataset() { + const nextGraphLdoDataset = new ConnectedLdoDataset( + [mockConnectedPlugin], + createDatasetFactory(), + createTransactionDatasetFactory(), + ); + return nextGraphLdoDataset; +} diff --git a/packages/connected/test/mocks/MockConnectedPlugin.ts b/packages/connected/test/mocks/MockConnectedPlugin.ts new file mode 100644 index 0000000..12678b5 --- /dev/null +++ b/packages/connected/test/mocks/MockConnectedPlugin.ts @@ -0,0 +1,45 @@ +import type { ConnectedContext, ConnectedPlugin } from "@ldo/connected"; +import { MockResource } from "./MockResource.js"; +import { v4 } from "uuid"; + +/** + * The Type of the SolidConnectedContext + */ +export interface MockConnectedContext {} + +export interface MockConnectedPlugin + extends ConnectedPlugin< + "mock", + string, + MockResource, + MockConnectedContext, + undefined + > { + name: "mock"; + getResource: (uri: string, context: ConnectedContext) => MockResource; + createResource(context: ConnectedContext): Promise; +} + +export const mockConnectedPlugin: MockConnectedPlugin = { + name: "mock", + + getResource: function ( + uri: string, + _context: ConnectedContext, + ): MockResource { + return new MockResource(uri); + }, + + createResource: async function (): Promise { + return new MockResource(v4()); + }, + + isUriValid: function (uri: string): uri is string { + return typeof uri === "string"; + }, + + initialContext: {}, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore "Types" only exists for the typing system + types: {}, +}; diff --git a/packages/jsonld-dataset-proxy/src/setLanguagePreferences.ts b/packages/jsonld-dataset-proxy/src/setLanguagePreferences.ts index 9f6d9e6..6d007a1 100644 --- a/packages/jsonld-dataset-proxy/src/setLanguagePreferences.ts +++ b/packages/jsonld-dataset-proxy/src/setLanguagePreferences.ts @@ -1,6 +1,6 @@ import type { LanguageOrdering } from "./language/languageTypes.js"; import type { InteractOptions } from "./util/createInteractOptions.js"; -import { createInteractOptions } from "./util/createInteractOptions.js"; +import { createProxyInteractOptions } from "./util/createInteractOptions.js"; /** * Set the default language pr @@ -10,5 +10,5 @@ import { createInteractOptions } from "./util/createInteractOptions.js"; export function setLanguagePreferences( ...languageOrdering: LanguageOrdering ): InteractOptions { - return createInteractOptions("languageOrdering", languageOrdering); + return createProxyInteractOptions("languageOrdering", languageOrdering); } diff --git a/packages/jsonld-dataset-proxy/src/util/createInteractOptions.ts b/packages/jsonld-dataset-proxy/src/util/createInteractOptions.ts index f498e3d..84eb06f 100644 --- a/packages/jsonld-dataset-proxy/src/util/createInteractOptions.ts +++ b/packages/jsonld-dataset-proxy/src/util/createInteractOptions.ts @@ -19,7 +19,7 @@ export interface InteractOptions { usingCopy(...objects: T[]): T[]; } -export function createInteractOptions( +export function createProxyInteractOptions( paramKey: string, parameter: unknown, ): InteractOptions { diff --git a/packages/jsonld-dataset-proxy/src/write.ts b/packages/jsonld-dataset-proxy/src/write.ts index 095b615..ee4cf31 100644 --- a/packages/jsonld-dataset-proxy/src/write.ts +++ b/packages/jsonld-dataset-proxy/src/write.ts @@ -1,6 +1,6 @@ import type { GraphNode } from "@ldo/rdf-utils"; import type { InteractOptions } from "./util/createInteractOptions.js"; -import { createInteractOptions } from "./util/createInteractOptions.js"; +import { createProxyInteractOptions } from "./util/createInteractOptions.js"; /** * Set the graphs that should be written to @@ -8,5 +8,5 @@ import { createInteractOptions } from "./util/createInteractOptions.js"; * @returns a write builder */ export function write(...graphs: GraphNode[]): InteractOptions { - return createInteractOptions("writeGraphs", graphs); + return createProxyInteractOptions("writeGraphs", graphs); } diff --git a/packages/react/package.json b/packages/react/package.json index 105863f..2d78d5b 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -36,9 +36,11 @@ "homepage": "https://github.com/o-development/ldo/tree/main/packages/solid-react#readme", "devDependencies": { "@rdfjs/types": "^1.0.1", - "@testing-library/react": "^14.1.2", - "start-server-and-test": "^2.0.3", - "ts-node": "^10.9.2" + "@testing-library/jest-dom": "^6.7.0", + "@testing-library/react": "^14.3.1", + "@testing-library/user-event": "^14.6.1", + "jsdom": "^26.1.0", + "vitest": "^3.2.4" }, "dependencies": { "@ldo/connected": "^1.0.0-alpha.30", diff --git a/packages/react/src/createLdoReactMethods.tsx b/packages/react/src/createLdoReactMethods.tsx index f7d13a9..689ba33 100644 --- a/packages/react/src/createLdoReactMethods.tsx +++ b/packages/react/src/createLdoReactMethods.tsx @@ -10,6 +10,11 @@ import { createUseResource } from "./methods/useResource.js"; import { createUseSubject } from "./methods/useSubject.js"; import { createUseSubscribeToResource } from "./methods/useSubscribeToResource.js"; import { createUseLinkQuery } from "./methods/useLinkQuery.js"; +import { createUseDataset } from "./methods/useDataset.js"; +import { createUseChangeDataset } from "./methods/change/useChangeDataset.js"; +import { createUseChangeSubject } from "./methods/change/useChangeSubject.js"; +import { createUseChangeMatchObject } from "./methods/change/useChangeMatchObject.js"; +import { createUseChangeMatchSubject } from "./methods/change/useChangeMatchSubject.js"; /** * A function that creates all common react functions given specific plugin. @@ -23,14 +28,18 @@ import { createUseLinkQuery } from "./methods/useLinkQuery.js"; * * // Export the results to be used in the reset of the application * export const { - * dataset, - * useLdo, - * useMatchObject, - * useMatchSubject, - * useResource, - * useSubject, - * useSubscribeToResource, - * useLinkQuery, + * dataset, + * useLdo, + * useMatchObject, + * useMatchSubject, + * useResource, + * useSubject, + * useSubscribeToResource, + * useLinkQuery, + * useChangeDataset, + * useChangeSubject, + * useChangeMatchObject, + * useChangeMatchSubject, * } = createLdoReactMethods([ * solidConnectedPlugin, * nextGraphConnectedPlugin @@ -66,6 +75,7 @@ export function createLdoReactMethods< return { dataset, + useDataset: createUseDataset(dataset), useLdo: createUseLdo(dataset), useMatchObject: createUseMatchObject(dataset), useMatchSubject: createUseMatchSubject(dataset), @@ -73,5 +83,9 @@ export function createLdoReactMethods< useSubject: createUseSubject(dataset), useSubscribeToResource: createUseSubscribeToResource(dataset), useLinkQuery: createUseLinkQuery(dataset), + useChangeDataset: createUseChangeDataset(dataset), + useChangeSubject: createUseChangeSubject(dataset), + useChangeMatchObject: createUseChangeMatchObject(dataset), + useChangeMatchSubject: createUseChangeMatchSubject(dataset), }; } diff --git a/packages/react/src/methods/change/types.ts b/packages/react/src/methods/change/types.ts new file mode 100644 index 0000000..cabb35c --- /dev/null +++ b/packages/react/src/methods/change/types.ts @@ -0,0 +1,23 @@ +import type { + ConnectedLdoTransactionDataset, + ConnectedPlugin, +} from "@ldo/connected"; +import type { LdoBase, LdSet } from "@ldo/ldo"; + +export type useChangeReturn = [ + Type, + useChangeSetData, + useChangeCommitData, +]; + +type BaseOtherType = LdoBase | LdSet; + +export type useChangeSetData = < + OtherType extends BaseOtherType | undefined = undefined, +>( + changer: (toChange: OtherType extends undefined ? T : OtherType) => void, + input?: OtherType, +) => void; + +export type useChangeCommitData = + () => ReturnType["commitToRemote"]>; diff --git a/packages/react/src/methods/change/useChangeDataset.ts b/packages/react/src/methods/change/useChangeDataset.ts new file mode 100644 index 0000000..55ba4df --- /dev/null +++ b/packages/react/src/methods/change/useChangeDataset.ts @@ -0,0 +1,58 @@ +import { useCallback, useMemo } from "react"; +import type { + ConnectedLdoDataset, + ConnectedLdoTransactionDataset, + ConnectedPlugin, + IConnectedLdoDataset, +} from "@ldo/connected"; +import type { useChangeCommitData } from "./types.js"; + +export type useChangeDatasetReturn = [ + ConnectedLdoTransactionDataset, + useChangeSetDataset, + useChangeCommitData, +]; + +export type useChangeSetDataset = ( + changer: (toChange: ConnectedLdoTransactionDataset) => void, +) => void; + +/** + * @internal + * + * Creates a useChangeDataset function + */ +export function createUseChangeDataset( + dataset: ConnectedLdoDataset, +) { + /** + * Returns a transaction on the dataset that can be modified and committed + */ + return function useChangeDataset( + specificDataset?: IConnectedLdoDataset, + ): useChangeDatasetReturn { + const transactionDataset = useMemo(() => { + return ( + specificDataset ?? dataset + ).startTransaction() as ConnectedLdoTransactionDataset; + }, [specificDataset]); + + const setData = useCallback>( + (changer) => { + const subTransaction = transactionDataset.startTransaction(); + changer(subTransaction); + subTransaction.commit(); + }, + [transactionDataset], + ); + + const commitData = useCallback>(() => { + return transactionDataset.commitToRemote(); + }, [transactionDataset]); + + return useMemo( + () => [transactionDataset, setData, commitData], + [transactionDataset, setData, commitData], + ); + }; +} diff --git a/packages/react/src/methods/change/useChangeMatchObject.ts b/packages/react/src/methods/change/useChangeMatchObject.ts new file mode 100644 index 0000000..037b736 --- /dev/null +++ b/packages/react/src/methods/change/useChangeMatchObject.ts @@ -0,0 +1,60 @@ +import { useCallback, useMemo } from "react"; +import type { ConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected"; +import { createUseChangeDataset } from "./useChangeDataset.js"; +import type { LdoBase, LdSet, ShapeType } from "@ldo/ldo"; +import type { QuadMatch } from "@ldo/rdf-utils"; +import type { UseMatchObjectOptions } from "../useMatchObject.js"; +import { createUseMatchObject } from "../useMatchObject.js"; +import type { useChangeReturn, useChangeSetData } from "./types.js"; + +/** + * @internal + * + * Creates a useChangeMatchObject function + */ +export function createUseChangeMatchObject( + dataset: ConnectedLdoDataset, +) { + const useChangeDataset = createUseChangeDataset(dataset); + const useMatchObject = createUseMatchObject(dataset); + + /** + * Returns a list of matched objects that can be modified and committed + */ + return function useChangeSubject( + shapeType: ShapeType, + writeResource: Plugins[number]["types"]["resource"], + subject?: QuadMatch[0] | string, + predicate?: QuadMatch[1] | string, + graph?: QuadMatch[3] | string, + options?: UseMatchObjectOptions, + ): useChangeReturn, Plugins> { + const [transactionDataset, setDataset, commitData] = useChangeDataset( + options?.dataset, + ); + + const ldObjects = useMatchObject(shapeType, subject, predicate, graph, { + dataset: transactionDataset, + }); + + const setData = useCallback>>( + (changer) => { + setDataset((dataset) => { + const ldSet = dataset + .usingType(shapeType) + .write(writeResource.uri) + .matchObject(subject, predicate, graph); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + changer(ldSet); + }); + }, + [setDataset, subject, predicate, graph, shapeType, writeResource], + ); + + return useMemo( + () => [ldObjects, setData, commitData], + [ldObjects, setData, commitData], + ); + }; +} diff --git a/packages/react/src/methods/change/useChangeMatchSubject.ts b/packages/react/src/methods/change/useChangeMatchSubject.ts new file mode 100644 index 0000000..8978cce --- /dev/null +++ b/packages/react/src/methods/change/useChangeMatchSubject.ts @@ -0,0 +1,62 @@ +import { useCallback, useMemo } from "react"; +import type { ConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected"; +import { createUseChangeDataset } from "./useChangeDataset.js"; +import type { LdoBase, LdSet, ShapeType } from "@ldo/ldo"; +import type { QuadMatch } from "@ldo/rdf-utils"; +import type { useChangeReturn, useChangeSetData } from "./types.js"; +import { + createUseMatchSubject, + type UseMatchSubjectOptions, +} from "../useMatchSubject.js"; + +/** + * @internal + * + * Creates a useChangeMatchSubject function + */ +export function createUseChangeMatchSubject( + dataset: ConnectedLdoDataset, +) { + const useChangeDataset = createUseChangeDataset(dataset); + const useMatchSubject = createUseMatchSubject(dataset); + + /** + * Returns a list of matched subjects that can be modified and committed + */ + return function useChangeSubject( + shapeType: ShapeType, + writeResource: Plugins[number]["types"]["resource"], + predicate?: QuadMatch[1] | string, + object?: QuadMatch[2] | string, + graph?: QuadMatch[3] | string, + options?: UseMatchSubjectOptions, + ): useChangeReturn, Plugins> { + const [transactionDataset, setDataset, commitData] = useChangeDataset( + options?.dataset, + ); + + const ldSubjects = useMatchSubject(shapeType, predicate, object, graph, { + dataset: transactionDataset, + }); + + const setData = useCallback>>( + (changer) => { + setDataset((dataset) => { + const ldSet = dataset + .usingType(shapeType) + .write(writeResource.uri) + .matchSubject(predicate, object, graph); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + changer(ldSet); + }); + }, + [setDataset, object, predicate, graph, shapeType, writeResource], + ); + + return useMemo( + () => [ldSubjects, setData, commitData], + [ldSubjects, setData, commitData], + ); + }; +} diff --git a/packages/react/src/methods/change/useChangeSubject.ts b/packages/react/src/methods/change/useChangeSubject.ts new file mode 100644 index 0000000..82d07f3 --- /dev/null +++ b/packages/react/src/methods/change/useChangeSubject.ts @@ -0,0 +1,85 @@ +import { useCallback, useMemo } from "react"; +import type { ConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected"; +import { createUseChangeDataset } from "./useChangeDataset.js"; +import type { UseSubjectOptions } from "../useSubject.js"; +import { createUseSubject } from "../useSubject.js"; +import type { LdoBase, ShapeType } from "@ldo/ldo"; +import type { SubjectNode } from "@ldo/rdf-utils"; +import type { useChangeReturn, useChangeSetData } from "./types.js"; +import { createProxyInteractOptions } from "@ldo/jsonld-dataset-proxy"; + +export type useChangeSubjectType = { + ( + shapeType: ShapeType, + writeResource: Plugins[number]["types"]["resource"], + subject: string | SubjectNode, + options?: UseSubjectOptions, + ): useChangeReturn; + ( + shapeType: ShapeType, + writeResource: Plugins[number]["types"]["resource"], + subject?: string | SubjectNode, + options?: UseSubjectOptions, + ): useChangeReturn; + ( + shapeType: ShapeType, + writeResource: Plugins[number]["types"]["resource"], + subject?: string | SubjectNode, + options?: UseSubjectOptions, + ): useChangeReturn; +}; + +/** + * @internal + * + * Creates a useChangeSubject function + */ +export function createUseChangeSubject( + dataset: ConnectedLdoDataset, +): useChangeSubjectType { + const useChangeDataset = createUseChangeDataset(dataset); + const useSubject = createUseSubject(dataset); + + /** + * Returns a subject that can be modified and committed + */ + return function useChangeSubject( + shapeType: ShapeType, + writeResource: Plugins[number]["types"]["resource"], + subject?: string | SubjectNode, + options?: UseSubjectOptions, + ): useChangeReturn { + const [transactionDataset, setDataset, commitData] = useChangeDataset( + options?.dataset, + ); + + const ldObject = useSubject(shapeType, subject, { + dataset: transactionDataset, + }); + + const setData = useCallback>( + (changer, otherType?) => { + if (!subject) return; + setDataset((dataset) => { + const ldObject = otherType + ? createProxyInteractOptions("dataset", dataset).usingCopy( + otherType, + ) + : dataset + .usingType(shapeType) + .write(writeResource.uri) + .fromSubject(subject); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + changer(ldObject); + }); + }, + [setDataset, subject, shapeType, writeResource], + ); + + return useMemo( + () => [ldObject, setData, commitData], + [ldObject, setData, commitData], + ); + }; +} diff --git a/packages/react/src/methods/useDataset.ts b/packages/react/src/methods/useDataset.ts new file mode 100644 index 0000000..70207bf --- /dev/null +++ b/packages/react/src/methods/useDataset.ts @@ -0,0 +1,17 @@ +import { ConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected"; + +/** + * @internal + * + * Creates a useDataset function + */ +export function createUseDataset( + dataset: ConnectedLdoDataset, +) { + /** + * Returns the global dataset for the application + */ + return function useDataset() { + return dataset; + } +} \ No newline at end of file diff --git a/packages/react/src/methods/useMatchObject.ts b/packages/react/src/methods/useMatchObject.ts index 38da77a..abc00e5 100644 --- a/packages/react/src/methods/useMatchObject.ts +++ b/packages/react/src/methods/useMatchObject.ts @@ -3,7 +3,15 @@ import type { QuadMatch } from "@ldo/rdf-utils"; import type { LdoBuilder } from "@ldo/ldo"; import { useCallback } from "react"; import { useTrackingProxy } from "../util/useTrackingProxy.js"; -import type { ConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected"; +import type { + ConnectedLdoDataset, + ConnectedPlugin, + IConnectedLdoDataset, +} from "@ldo/connected"; + +export interface UseMatchObjectOptions { + dataset?: IConnectedLdoDataset; +} /** * @internal @@ -22,6 +30,7 @@ export function createUseMatchObject( subject?: QuadMatch[0] | string, predicate?: QuadMatch[1] | string, graph?: QuadMatch[3] | string, + options?: UseMatchObjectOptions, ): LdSet { const matchObject = useCallback( (builder: LdoBuilder) => { @@ -30,6 +39,10 @@ export function createUseMatchObject( [subject, predicate, graph], ); - return useTrackingProxy(shapeType, matchObject, dataset); + return useTrackingProxy( + shapeType, + matchObject, + options?.dataset ?? dataset, + ); }; } diff --git a/packages/react/src/methods/useMatchSubject.ts b/packages/react/src/methods/useMatchSubject.ts index 64270e2..127012d 100644 --- a/packages/react/src/methods/useMatchSubject.ts +++ b/packages/react/src/methods/useMatchSubject.ts @@ -3,7 +3,15 @@ import type { QuadMatch } from "@ldo/rdf-utils"; import type { LdoBuilder } from "@ldo/ldo"; import { useCallback } from "react"; import { useTrackingProxy } from "../util/useTrackingProxy.js"; -import type { ConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected"; +import type { + ConnectedLdoDataset, + ConnectedPlugin, + IConnectedLdoDataset, +} from "@ldo/connected"; + +export interface UseMatchSubjectOptions { + dataset?: IConnectedLdoDataset; +} /** * @internal @@ -22,6 +30,7 @@ export function createUseMatchSubject( predicate?: QuadMatch[1] | string, object?: QuadMatch[2] | string, graph?: QuadMatch[3] | string, + options?: UseMatchSubjectOptions, ): LdSet { const matchSubject = useCallback( (builder: LdoBuilder) => { @@ -30,6 +39,10 @@ export function createUseMatchSubject( [predicate, object, graph], ); - return useTrackingProxy(shapeType, matchSubject, dataset); + return useTrackingProxy( + shapeType, + matchSubject, + options?.dataset ?? dataset, + ); }; } diff --git a/packages/react/src/methods/useSubject.ts b/packages/react/src/methods/useSubject.ts index 8c460e4..e198b03 100644 --- a/packages/react/src/methods/useSubject.ts +++ b/packages/react/src/methods/useSubject.ts @@ -5,20 +5,31 @@ import type { LdoBase } from "@ldo/ldo"; import { useCallback } from "react"; import { useTrackingProxy } from "../util/useTrackingProxy.js"; -import type { ConnectedLdoDataset, ConnectedPlugin } from "@ldo/connected"; +import type { + ConnectedLdoDataset, + ConnectedPlugin, + IConnectedLdoDataset, +} from "@ldo/connected"; -export type useSubjectType = { +export interface UseSubjectOptions { + dataset?: IConnectedLdoDataset; +} + +export type useSubjectType = { ( shapeType: ShapeType, subject: string | SubjectNode, + options?: UseSubjectOptions, ): Type; ( shapeType: ShapeType, subject?: string | SubjectNode, + options?: UseSubjectOptions, ): Type | undefined; ( shapeType: ShapeType, subject?: string | SubjectNode, + options?: UseSubjectOptions, ): Type | undefined; }; @@ -29,7 +40,7 @@ export type useSubjectType = { */ export function createUseSubject( dataset: ConnectedLdoDataset, -): useSubjectType { +): useSubjectType { /** * Returns a Linked Data Object based on the provided subject. Triggers a * rerender if the data is udpated. @@ -37,6 +48,7 @@ export function createUseSubject( return function useSubject( shapeType: ShapeType, subject?: string | SubjectNode, + options?: UseSubjectOptions, ): Type | undefined { const fromSubject = useCallback( (builder: LdoBuilder) => { @@ -46,6 +58,10 @@ export function createUseSubject( [subject], ); - return useTrackingProxy(shapeType, fromSubject, dataset); + return useTrackingProxy( + shapeType, + fromSubject, + options?.dataset ?? dataset, + ); }; } diff --git a/packages/react/test/.ldo/post.context.ts b/packages/react/test/.ldo/post.context.ts new file mode 100644 index 0000000..5cb3a91 --- /dev/null +++ b/packages/react/test/.ldo/post.context.ts @@ -0,0 +1,32 @@ +import { ContextDefinition } from "jsonld"; + +/** + * ============================================================================= + * postContext: JSONLD Context for post + * ============================================================================= + */ +export const postContext: ContextDefinition = { + type: { + "@id": "@type", + }, + SocialMediaPosting: "http://schema.org/SocialMediaPosting", + CreativeWork: "http://schema.org/CreativeWork", + Thing: "http://schema.org/Thing", + articleBody: { + "@id": "http://schema.org/articleBody", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + uploadDate: { + "@id": "http://schema.org/uploadDate", + "@type": "http://www.w3.org/2001/XMLSchema#date", + }, + image: { + "@id": "http://schema.org/image", + "@type": "@id", + }, + publisher: { + "@id": "http://schema.org/publisher", + "@type": "@id", + "@container": "@set", + }, +}; diff --git a/packages/react/test/.ldo/post.schema.ts b/packages/react/test/.ldo/post.schema.ts new file mode 100644 index 0000000..39e8b63 --- /dev/null +++ b/packages/react/test/.ldo/post.schema.ts @@ -0,0 +1,155 @@ +import { Schema } from "shexj"; + +/** + * ============================================================================= + * postSchema: ShexJ Schema for post + * ============================================================================= + */ +export const postSchema: Schema = { + type: "Schema", + shapes: [ + { + id: "https://example.com/PostSh", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: [ + "http://schema.org/SocialMediaPosting", + "http://schema.org/CreativeWork", + "http://schema.org/Thing", + ], + }, + }, + { + type: "TripleConstraint", + predicate: "http://schema.org/articleBody", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#label", + object: { + value: "articleBody", + }, + }, + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The actual body of the article. ", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://schema.org/uploadDate", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#date", + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#label", + object: { + value: "uploadDate", + }, + }, + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "Date when this media object was uploaded to this site.", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://schema.org/image", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#label", + object: { + value: "image", + }, + }, + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "A media object that encodes this CreativeWork. This property is a synonym for encoding.", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://schema.org/publisher", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#label", + object: { + value: "publisher", + }, + }, + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The publisher of the creative work.", + }, + }, + ], + }, + ], + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#label", + object: { + value: "SocialMediaPost", + }, + }, + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "A post to a social media platform, including blog posts, tweets, Facebook posts, etc.", + }, + }, + ], + }, + }, + ], +}; diff --git a/packages/react/test/.ldo/post.shapeTypes.ts b/packages/react/test/.ldo/post.shapeTypes.ts new file mode 100644 index 0000000..aa112e7 --- /dev/null +++ b/packages/react/test/.ldo/post.shapeTypes.ts @@ -0,0 +1,19 @@ +import { ShapeType } from "@ldo/ldo"; +import { postSchema } from "./post.schema.js"; +import { postContext } from "./post.context.js"; +import { PostSh } from "./post.typings.js"; + +/** + * ============================================================================= + * LDO ShapeTypes post + * ============================================================================= + */ + +/** + * PostSh ShapeType + */ +export const PostShShapeType: ShapeType = { + schema: postSchema, + shape: "https://example.com/PostSh", + context: postContext, +}; diff --git a/packages/react/test/.ldo/post.typings.ts b/packages/react/test/.ldo/post.typings.ts new file mode 100644 index 0000000..bf9ac17 --- /dev/null +++ b/packages/react/test/.ldo/post.typings.ts @@ -0,0 +1,45 @@ +import { LdSet, LdoJsonldContext } from "@ldo/ldo"; + +/** + * ============================================================================= + * Typescript Typings for post + * ============================================================================= + */ + +/** + * PostSh Type + */ +export interface PostSh { + "@id"?: string; + "@context"?: LdoJsonldContext; + type: + | { + "@id": "SocialMediaPosting"; + } + | { + "@id": "CreativeWork"; + } + | { + "@id": "Thing"; + }; + /** + * The actual body of the article. + */ + articleBody?: string; + /** + * Date when this media object was uploaded to this site. + */ + uploadDate: string; + /** + * A media object that encodes this CreativeWork. This property is a synonym for encoding. + */ + image?: { + "@id": string; + }; + /** + * The publisher of the creative work. + */ + publisher: LdSet<{ + "@id": string; + }>; +} diff --git a/packages/react/test/.ldo/solidProfile.context.ts b/packages/react/test/.ldo/solidProfile.context.ts new file mode 100644 index 0000000..9fdffc3 --- /dev/null +++ b/packages/react/test/.ldo/solidProfile.context.ts @@ -0,0 +1,459 @@ +import { LdoJsonldContext } from "@ldo/ldo"; + +/** + * ============================================================================= + * solidProfileContext: JSONLD Context for solidProfile + * ============================================================================= + */ +export const solidProfileContext: LdoJsonldContext = { + type: { + "@id": "@type", + }, + Person: { + "@id": "http://schema.org/Person", + "@context": { + type: { + "@id": "@type", + }, + fn: { + "@id": "http://www.w3.org/2006/vcard/ns#fn", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + name: { + "@id": "http://xmlns.com/foaf/0.1/name", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + hasAddress: { + "@id": "http://www.w3.org/2006/vcard/ns#hasAddress", + "@type": "@id", + "@isCollection": true, + }, + hasEmail: { + "@id": "http://www.w3.org/2006/vcard/ns#hasEmail", + "@type": "@id", + "@isCollection": true, + }, + hasPhoto: { + "@id": "http://www.w3.org/2006/vcard/ns#hasPhoto", + "@type": "@id", + }, + img: { + "@id": "http://xmlns.com/foaf/0.1/img", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + hasTelephone: { + "@id": "http://www.w3.org/2006/vcard/ns#hasTelephone", + "@type": "@id", + "@isCollection": true, + }, + phone: { + "@id": "http://www.w3.org/2006/vcard/ns#phone", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + organizationName: { + "@id": "http://www.w3.org/2006/vcard/ns#organization-name", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + role: { + "@id": "http://www.w3.org/2006/vcard/ns#role", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + trustedApp: { + "@id": "http://www.w3.org/ns/auth/acl#trustedApp", + "@type": "@id", + "@isCollection": true, + }, + key: { + "@id": "http://www.w3.org/ns/auth/cert#key", + "@type": "@id", + "@isCollection": true, + }, + inbox: { + "@id": "http://www.w3.org/ns/ldp#inbox", + "@type": "@id", + }, + preferencesFile: { + "@id": "http://www.w3.org/ns/pim/space#preferencesFile", + "@type": "@id", + }, + storage: { + "@id": "http://www.w3.org/ns/pim/space#storage", + "@type": "@id", + "@isCollection": true, + }, + account: { + "@id": "http://www.w3.org/ns/solid/terms#account", + "@type": "@id", + }, + privateTypeIndex: { + "@id": "http://www.w3.org/ns/solid/terms#privateTypeIndex", + "@type": "@id", + "@isCollection": true, + }, + publicTypeIndex: { + "@id": "http://www.w3.org/ns/solid/terms#publicTypeIndex", + "@type": "@id", + "@isCollection": true, + }, + knows: { + "@id": "http://xmlns.com/foaf/0.1/knows", + "@type": "@id", + "@isCollection": true, + }, + }, + }, + Person2: { + "@id": "http://xmlns.com/foaf/0.1/Person", + "@context": { + type: { + "@id": "@type", + }, + fn: { + "@id": "http://www.w3.org/2006/vcard/ns#fn", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + name: { + "@id": "http://xmlns.com/foaf/0.1/name", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + hasAddress: { + "@id": "http://www.w3.org/2006/vcard/ns#hasAddress", + "@type": "@id", + "@isCollection": true, + }, + hasEmail: { + "@id": "http://www.w3.org/2006/vcard/ns#hasEmail", + "@type": "@id", + "@isCollection": true, + }, + hasPhoto: { + "@id": "http://www.w3.org/2006/vcard/ns#hasPhoto", + "@type": "@id", + }, + img: { + "@id": "http://xmlns.com/foaf/0.1/img", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + hasTelephone: { + "@id": "http://www.w3.org/2006/vcard/ns#hasTelephone", + "@type": "@id", + "@isCollection": true, + }, + phone: { + "@id": "http://www.w3.org/2006/vcard/ns#phone", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + organizationName: { + "@id": "http://www.w3.org/2006/vcard/ns#organization-name", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + role: { + "@id": "http://www.w3.org/2006/vcard/ns#role", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + trustedApp: { + "@id": "http://www.w3.org/ns/auth/acl#trustedApp", + "@type": "@id", + "@isCollection": true, + }, + key: { + "@id": "http://www.w3.org/ns/auth/cert#key", + "@type": "@id", + "@isCollection": true, + }, + inbox: { + "@id": "http://www.w3.org/ns/ldp#inbox", + "@type": "@id", + }, + preferencesFile: { + "@id": "http://www.w3.org/ns/pim/space#preferencesFile", + "@type": "@id", + }, + storage: { + "@id": "http://www.w3.org/ns/pim/space#storage", + "@type": "@id", + "@isCollection": true, + }, + account: { + "@id": "http://www.w3.org/ns/solid/terms#account", + "@type": "@id", + }, + privateTypeIndex: { + "@id": "http://www.w3.org/ns/solid/terms#privateTypeIndex", + "@type": "@id", + "@isCollection": true, + }, + publicTypeIndex: { + "@id": "http://www.w3.org/ns/solid/terms#publicTypeIndex", + "@type": "@id", + "@isCollection": true, + }, + knows: { + "@id": "http://xmlns.com/foaf/0.1/knows", + "@type": "@id", + "@isCollection": true, + }, + }, + }, + fn: { + "@id": "http://www.w3.org/2006/vcard/ns#fn", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + name: { + "@id": "http://xmlns.com/foaf/0.1/name", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + hasAddress: { + "@id": "http://www.w3.org/2006/vcard/ns#hasAddress", + "@type": "@id", + "@isCollection": true, + }, + countryName: { + "@id": "http://www.w3.org/2006/vcard/ns#country-name", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + locality: { + "@id": "http://www.w3.org/2006/vcard/ns#locality", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + postalCode: { + "@id": "http://www.w3.org/2006/vcard/ns#postal-code", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + region: { + "@id": "http://www.w3.org/2006/vcard/ns#region", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + streetAddress: { + "@id": "http://www.w3.org/2006/vcard/ns#street-address", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + hasEmail: { + "@id": "http://www.w3.org/2006/vcard/ns#hasEmail", + "@type": "@id", + "@isCollection": true, + }, + Dom: { + "@id": "http://www.w3.org/2006/vcard/ns#Dom", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + Home: { + "@id": "http://www.w3.org/2006/vcard/ns#Home", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + ISDN: { + "@id": "http://www.w3.org/2006/vcard/ns#ISDN", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + Internet: { + "@id": "http://www.w3.org/2006/vcard/ns#Internet", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + Intl: { + "@id": "http://www.w3.org/2006/vcard/ns#Intl", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + Label: { + "@id": "http://www.w3.org/2006/vcard/ns#Label", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + Parcel: { + "@id": "http://www.w3.org/2006/vcard/ns#Parcel", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + Postal: { + "@id": "http://www.w3.org/2006/vcard/ns#Postal", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + Pref: { + "@id": "http://www.w3.org/2006/vcard/ns#Pref", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + Work: { + "@id": "http://www.w3.org/2006/vcard/ns#Work", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + X400: { + "@id": "http://www.w3.org/2006/vcard/ns#X400", + "@context": { + type: { + "@id": "@type", + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + }, + }, + value: { + "@id": "http://www.w3.org/2006/vcard/ns#value", + "@type": "@id", + }, + hasPhoto: { + "@id": "http://www.w3.org/2006/vcard/ns#hasPhoto", + "@type": "@id", + }, + img: { + "@id": "http://xmlns.com/foaf/0.1/img", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + hasTelephone: { + "@id": "http://www.w3.org/2006/vcard/ns#hasTelephone", + "@type": "@id", + "@isCollection": true, + }, + phone: { + "@id": "http://www.w3.org/2006/vcard/ns#phone", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + organizationName: { + "@id": "http://www.w3.org/2006/vcard/ns#organization-name", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + role: { + "@id": "http://www.w3.org/2006/vcard/ns#role", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + trustedApp: { + "@id": "http://www.w3.org/ns/auth/acl#trustedApp", + "@type": "@id", + "@isCollection": true, + }, + mode: { + "@id": "http://www.w3.org/ns/auth/acl#mode", + "@isCollection": true, + }, + Append: "http://www.w3.org/ns/auth/acl#Append", + Control: "http://www.w3.org/ns/auth/acl#Control", + Read: "http://www.w3.org/ns/auth/acl#Read", + Write: "http://www.w3.org/ns/auth/acl#Write", + origin: { + "@id": "http://www.w3.org/ns/auth/acl#origin", + "@type": "@id", + }, + key: { + "@id": "http://www.w3.org/ns/auth/cert#key", + "@type": "@id", + "@isCollection": true, + }, + modulus: { + "@id": "http://www.w3.org/ns/auth/cert#modulus", + "@type": "http://www.w3.org/2001/XMLSchema#string", + }, + exponent: { + "@id": "http://www.w3.org/ns/auth/cert#exponent", + "@type": "http://www.w3.org/2001/XMLSchema#integer", + }, + inbox: { + "@id": "http://www.w3.org/ns/ldp#inbox", + "@type": "@id", + }, + preferencesFile: { + "@id": "http://www.w3.org/ns/pim/space#preferencesFile", + "@type": "@id", + }, + storage: { + "@id": "http://www.w3.org/ns/pim/space#storage", + "@type": "@id", + "@isCollection": true, + }, + account: { + "@id": "http://www.w3.org/ns/solid/terms#account", + "@type": "@id", + }, + privateTypeIndex: { + "@id": "http://www.w3.org/ns/solid/terms#privateTypeIndex", + "@type": "@id", + "@isCollection": true, + }, + publicTypeIndex: { + "@id": "http://www.w3.org/ns/solid/terms#publicTypeIndex", + "@type": "@id", + "@isCollection": true, + }, + knows: { + "@id": "http://xmlns.com/foaf/0.1/knows", + "@type": "@id", + "@isCollection": true, + }, +}; diff --git a/packages/react/test/.ldo/solidProfile.schema.ts b/packages/react/test/.ldo/solidProfile.schema.ts new file mode 100644 index 0000000..69466fc --- /dev/null +++ b/packages/react/test/.ldo/solidProfile.schema.ts @@ -0,0 +1,749 @@ +import { Schema } from "shexj"; + +/** + * ============================================================================= + * solidProfileSchema: ShexJ Schema for solidProfile + * ============================================================================= + */ +export const solidProfileSchema: Schema = { + type: "Schema", + shapes: [ + { + id: "https://shaperepo.com/schemas/solidProfile#SolidProfileShape", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: ["http://schema.org/Person"], + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "Defines the node as a Person (from Schema.org)", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: ["http://xmlns.com/foaf/0.1/Person"], + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "Defines the node as a Person (from foaf)", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#fn", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "The formatted name of a person. Example: John Smith", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://xmlns.com/foaf/0.1/name", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "An alternate way to define a person's name.", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#hasAddress", + valueExpr: + "https://shaperepo.com/schemas/solidProfile#AddressShape", + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The person's street address.", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#hasEmail", + valueExpr: + "https://shaperepo.com/schemas/solidProfile#EmailShape", + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The person's email.", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#hasPhoto", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "A link to the person's photo", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://xmlns.com/foaf/0.1/img", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "Photo link but in string form", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#hasTelephone", + valueExpr: + "https://shaperepo.com/schemas/solidProfile#PhoneNumberShape", + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "Person's telephone number", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#phone", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "An alternative way to define a person's telephone number using a string", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#organization-name", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "The name of the organization with which the person is affiliated", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#role", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "The name of the person's role in their organization", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/acl#trustedApp", + valueExpr: + "https://shaperepo.com/schemas/solidProfile#TrustedAppShape", + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "A list of app origins that are trusted by this user", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/cert#key", + valueExpr: + "https://shaperepo.com/schemas/solidProfile#RSAPublicKeyShape", + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "A list of RSA public keys that are associated with private keys the user holds.", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/ldp#inbox", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "The user's LDP inbox to which apps can post notifications", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/pim/space#preferencesFile", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The user's preferences", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/pim/space#storage", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "The location of a Solid storage server related to this WebId", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/solid/terms#account", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The user's account", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/solid/terms#privateTypeIndex", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "A registry of all types used on the user's Pod (for private access only)", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/solid/terms#publicTypeIndex", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "A registry of all types used on the user's Pod (for public access)", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://xmlns.com/foaf/0.1/knows", + valueExpr: + "https://shaperepo.com/schemas/solidProfile#SolidProfileShape", + min: 0, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "A list of WebIds for all the people this user knows.", + }, + }, + ], + }, + ], + }, + extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"], + }, + }, + { + id: "https://shaperepo.com/schemas/solidProfile#AddressShape", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#country-name", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The name of the user's country of residence", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#locality", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "The name of the user's locality (City, Town etc.) of residence", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#postal-code", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The user's postal code", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#region", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "The name of the user's region (State, Province etc.) of residence", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#street-address", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The user's street address", + }, + }, + ], + }, + ], + }, + }, + }, + { + id: "https://shaperepo.com/schemas/solidProfile#EmailShape", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: [ + "http://www.w3.org/2006/vcard/ns#Dom", + "http://www.w3.org/2006/vcard/ns#Home", + "http://www.w3.org/2006/vcard/ns#ISDN", + "http://www.w3.org/2006/vcard/ns#Internet", + "http://www.w3.org/2006/vcard/ns#Intl", + "http://www.w3.org/2006/vcard/ns#Label", + "http://www.w3.org/2006/vcard/ns#Parcel", + "http://www.w3.org/2006/vcard/ns#Postal", + "http://www.w3.org/2006/vcard/ns#Pref", + "http://www.w3.org/2006/vcard/ns#Work", + "http://www.w3.org/2006/vcard/ns#X400", + ], + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The type of email.", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#value", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "The value of an email as a mailto link (Example )", + }, + }, + ], + }, + ], + }, + extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"], + }, + }, + { + id: "https://shaperepo.com/schemas/solidProfile#PhoneNumberShape", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", + valueExpr: { + type: "NodeConstraint", + values: [ + "http://www.w3.org/2006/vcard/ns#Dom", + "http://www.w3.org/2006/vcard/ns#Home", + "http://www.w3.org/2006/vcard/ns#ISDN", + "http://www.w3.org/2006/vcard/ns#Internet", + "http://www.w3.org/2006/vcard/ns#Intl", + "http://www.w3.org/2006/vcard/ns#Label", + "http://www.w3.org/2006/vcard/ns#Parcel", + "http://www.w3.org/2006/vcard/ns#Postal", + "http://www.w3.org/2006/vcard/ns#Pref", + "http://www.w3.org/2006/vcard/ns#Work", + "http://www.w3.org/2006/vcard/ns#X400", + ], + }, + min: 0, + max: 1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "They type of Phone Number", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/2006/vcard/ns#value", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: + "The value of a phone number as a tel link (Example )", + }, + }, + ], + }, + ], + }, + extra: ["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"], + }, + }, + { + id: "https://shaperepo.com/schemas/solidProfile#TrustedAppShape", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/acl#mode", + valueExpr: { + type: "NodeConstraint", + values: [ + "http://www.w3.org/ns/auth/acl#Append", + "http://www.w3.org/ns/auth/acl#Control", + "http://www.w3.org/ns/auth/acl#Read", + "http://www.w3.org/ns/auth/acl#Write", + ], + }, + min: 1, + max: -1, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The level of access provided to this origin", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/acl#origin", + valueExpr: { + type: "NodeConstraint", + nodeKind: "iri", + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "The app origin the user trusts", + }, + }, + ], + }, + ], + }, + }, + }, + { + id: "https://shaperepo.com/schemas/solidProfile#RSAPublicKeyShape", + type: "ShapeDecl", + shapeExpr: { + type: "Shape", + expression: { + type: "EachOf", + expressions: [ + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/cert#modulus", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#string", + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "RSA Modulus", + }, + }, + ], + }, + { + type: "TripleConstraint", + predicate: "http://www.w3.org/ns/auth/cert#exponent", + valueExpr: { + type: "NodeConstraint", + datatype: "http://www.w3.org/2001/XMLSchema#integer", + }, + annotations: [ + { + type: "Annotation", + predicate: "http://www.w3.org/2000/01/rdf-schema#comment", + object: { + value: "RSA Exponent", + }, + }, + ], + }, + ], + }, + }, + }, + ], +}; diff --git a/packages/react/test/.ldo/solidProfile.shapeTypes.ts b/packages/react/test/.ldo/solidProfile.shapeTypes.ts new file mode 100644 index 0000000..2265cce --- /dev/null +++ b/packages/react/test/.ldo/solidProfile.shapeTypes.ts @@ -0,0 +1,64 @@ +import { ShapeType } from "@ldo/ldo"; +import { solidProfileSchema } from "./solidProfile.schema.js"; +import { solidProfileContext } from "./solidProfile.context.js"; +import { AddressShape, EmailShape, PhoneNumberShape, RSAPublicKeyShape, SolidProfileShape, TrustedAppShape } from "./solidProfile.typings.js"; + +/** + * ============================================================================= + * LDO ShapeTypes solidProfile + * ============================================================================= + */ + +/** + * SolidProfileShape ShapeType + */ +export const SolidProfileShapeShapeType: ShapeType = { + schema: solidProfileSchema, + shape: "https://shaperepo.com/schemas/solidProfile#SolidProfileShape", + context: solidProfileContext, +}; + +/** + * AddressShape ShapeType + */ +export const AddressShapeShapeType: ShapeType = { + schema: solidProfileSchema, + shape: "https://shaperepo.com/schemas/solidProfile#AddressShape", + context: solidProfileContext, +}; + +/** + * EmailShape ShapeType + */ +export const EmailShapeShapeType: ShapeType = { + schema: solidProfileSchema, + shape: "https://shaperepo.com/schemas/solidProfile#EmailShape", + context: solidProfileContext, +}; + +/** + * PhoneNumberShape ShapeType + */ +export const PhoneNumberShapeShapeType: ShapeType = { + schema: solidProfileSchema, + shape: "https://shaperepo.com/schemas/solidProfile#PhoneNumberShape", + context: solidProfileContext, +}; + +/** + * TrustedAppShape ShapeType + */ +export const TrustedAppShapeShapeType: ShapeType = { + schema: solidProfileSchema, + shape: "https://shaperepo.com/schemas/solidProfile#TrustedAppShape", + context: solidProfileContext, +}; + +/** + * RSAPublicKeyShape ShapeType + */ +export const RSAPublicKeyShapeShapeType: ShapeType = { + schema: solidProfileSchema, + shape: "https://shaperepo.com/schemas/solidProfile#RSAPublicKeyShape", + context: solidProfileContext, +}; diff --git a/packages/react/test/.ldo/solidProfile.typings.ts b/packages/react/test/.ldo/solidProfile.typings.ts new file mode 100644 index 0000000..95dbaef --- /dev/null +++ b/packages/react/test/.ldo/solidProfile.typings.ts @@ -0,0 +1,293 @@ +import { LdoJsonldContext, LdSet } from "@ldo/ldo"; + +/** + * ============================================================================= + * Typescript Typings for solidProfile + * ============================================================================= + */ + +/** + * SolidProfileShape Type + */ +export interface SolidProfileShape { + "@id"?: string; + "@context"?: LdoJsonldContext; + /** + * Defines the node as a Person (from Schema.org) | Defines the node as a Person (from foaf) + */ + type: LdSet< + | { + "@id": "Person"; + } + | { + "@id": "Person2"; + } + >; + /** + * The formatted name of a person. Example: John Smith + */ + fn?: string; + /** + * An alternate way to define a person's name. + */ + name?: string; + /** + * The person's street address. + */ + hasAddress?: LdSet; + /** + * The person's email. + */ + hasEmail?: LdSet; + /** + * A link to the person's photo + */ + hasPhoto?: { + "@id": string; + }; + /** + * Photo link but in string form + */ + img?: string; + /** + * Person's telephone number + */ + hasTelephone?: LdSet; + /** + * An alternative way to define a person's telephone number using a string + */ + phone?: string; + /** + * The name of the organization with which the person is affiliated + */ + organizationName?: string; + /** + * The name of the person's role in their organization + */ + role?: string; + /** + * A list of app origins that are trusted by this user + */ + trustedApp?: LdSet; + /** + * A list of RSA public keys that are associated with private keys the user holds. + */ + key?: LdSet; + /** + * The user's LDP inbox to which apps can post notifications + */ + inbox: { + "@id": string; + }; + /** + * The user's preferences + */ + preferencesFile?: { + "@id": string; + }; + /** + * The location of a Solid storage server related to this WebId + */ + storage?: LdSet<{ + "@id": string; + }>; + /** + * The user's account + */ + account?: { + "@id": string; + }; + /** + * A registry of all types used on the user's Pod (for private access only) + */ + privateTypeIndex?: LdSet<{ + "@id": string; + }>; + /** + * A registry of all types used on the user's Pod (for public access) + */ + publicTypeIndex?: LdSet<{ + "@id": string; + }>; + /** + * A list of WebIds for all the people this user knows. + */ + knows?: LdSet; +} + +/** + * AddressShape Type + */ +export interface AddressShape { + "@id"?: string; + "@context"?: LdoJsonldContext; + /** + * The name of the user's country of residence + */ + countryName?: string; + /** + * The name of the user's locality (City, Town etc.) of residence + */ + locality?: string; + /** + * The user's postal code + */ + postalCode?: string; + /** + * The name of the user's region (State, Province etc.) of residence + */ + region?: string; + /** + * The user's street address + */ + streetAddress?: string; +} + +/** + * EmailShape Type + */ +export interface EmailShape { + "@id"?: string; + "@context"?: LdoJsonldContext; + /** + * The type of email. + */ + type?: + | { + "@id": "Dom"; + } + | { + "@id": "Home"; + } + | { + "@id": "ISDN"; + } + | { + "@id": "Internet"; + } + | { + "@id": "Intl"; + } + | { + "@id": "Label"; + } + | { + "@id": "Parcel"; + } + | { + "@id": "Postal"; + } + | { + "@id": "Pref"; + } + | { + "@id": "Work"; + } + | { + "@id": "X400"; + }; + /** + * The value of an email as a mailto link (Example ) + */ + value: { + "@id": string; + }; +} + +/** + * PhoneNumberShape Type + */ +export interface PhoneNumberShape { + "@id"?: string; + "@context"?: LdoJsonldContext; + /** + * They type of Phone Number + */ + type?: + | { + "@id": "Dom"; + } + | { + "@id": "Home"; + } + | { + "@id": "ISDN"; + } + | { + "@id": "Internet"; + } + | { + "@id": "Intl"; + } + | { + "@id": "Label"; + } + | { + "@id": "Parcel"; + } + | { + "@id": "Postal"; + } + | { + "@id": "Pref"; + } + | { + "@id": "Work"; + } + | { + "@id": "X400"; + }; + /** + * The value of a phone number as a tel link (Example ) + */ + value: { + "@id": string; + }; +} + +/** + * TrustedAppShape Type + */ +export interface TrustedAppShape { + "@id"?: string; + "@context"?: LdoJsonldContext; + /** + * The level of access provided to this origin + */ + mode: LdSet< + | { + "@id": "Append"; + } + | { + "@id": "Control"; + } + | { + "@id": "Read"; + } + | { + "@id": "Write"; + } + >; + /** + * The app origin the user trusts + */ + origin: { + "@id": string; + }; +} + +/** + * RSAPublicKeyShape Type + */ +export interface RSAPublicKeyShape { + "@id"?: string; + "@context"?: LdoJsonldContext; + /** + * RSA Modulus + */ + modulus: string; + /** + * RSA Exponent + */ + exponent: number; +} diff --git a/packages/react/test/mockLdoMethods.ts b/packages/react/test/mockLdoMethods.ts new file mode 100644 index 0000000..1677b96 --- /dev/null +++ b/packages/react/test/mockLdoMethods.ts @@ -0,0 +1,17 @@ +import { createLdoReactMethods } from "../src/createLdoReactMethods.js"; +import { mockConnectedPlugin } from "../../connected/test/mocks/MockConnectedPlugin.js"; + +export const { + dataset, + useLdo, + useMatchObject, + useMatchSubject, + useResource, + useSubject, + useSubscribeToResource, + useLinkQuery, + useChangeDataset, + useChangeSubject, + useChangeMatchSubject, + useChangeMatchObject, +} = createLdoReactMethods([mockConnectedPlugin]); diff --git a/packages/react/test/trivial.test.ts b/packages/react/test/trivial.test.ts deleted file mode 100644 index 9110b03..0000000 --- a/packages/react/test/trivial.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { describe, it, expect } from "vitest"; - -describe("react", () => { - it("trivial", () => { - expect(true).toBe(true); - }); -}); diff --git a/packages/react/test/useLdoForm.test.tsx b/packages/react/test/useLdoForm.test.tsx new file mode 100644 index 0000000..86c60b5 --- /dev/null +++ b/packages/react/test/useLdoForm.test.tsx @@ -0,0 +1,227 @@ +// useChangeSubject.spec.tsx +/// +import { useResource, useChangeSubject, useSubject } from "./mockLdoMethods.js"; +import type { FunctionComponent } from "react"; +import React from "react"; +import { describe, it, expect, beforeEach } from "vitest"; +import { render, screen, within } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { SolidProfileShapeShapeType } from "./.ldo/solidProfile.shapeTypes.js"; +import { set } from "@ldo/jsonld-dataset-proxy"; +import "@testing-library/jest-dom/vitest"; + +/** + * Test component: deterministic friend IDs (Example1, Example2, ...), + * accessible labels, and committed data shown via useSubject. + */ +const FormTest: FunctionComponent = () => { + const randomResource = useResource("random"); + const submittedData = useSubject(SolidProfileShapeShapeType, "Example0"); + + const [data, setData, commitData] = useChangeSubject( + SolidProfileShapeShapeType, + randomResource, + "Example0", + ); + + return ( +
+

Form

+
{ + e.preventDefault(); + const result = await commitData(); + console.log(result); + }} + > + {/* Primary name field */} + + setData((profile) => { + profile.fn = e.target.value; + }) + } + /> + + {/* Friends */} + {data?.knows?.map((person) => ( +
+

{person["@id"]}

+ + setData((p) => { + p.fn = e.target.value; + }, person) + } + /> + +
+ ))} + + + + +
+ +
+ + {/* Committed view */} +

Submitted Data

+
+

Name: {submittedData?.fn ?? ""}

+
    + {submittedData?.knows?.map((person) => ( +
  • + Id: {person["@id"]} Name: {person.fn} +
  • + ))} +
+
+
+ ); +}; + +/** + * Spec: drives the UI as requested. + */ +describe("useChangeSubject", () => { + let user: ReturnType; + + beforeEach(() => { + user = userEvent.setup(); + }); + + it("handles typing, list add/remove, and commit cycles", async () => { + render(); + + // 1) Type "Example0" into the Name field, assert after each keystroke + const nameInput = screen.getByRole("textbox", { name: "Name" }); + const targetName = "Example0"; + let progressive = ""; + for (const c of targetName) { + progressive += c; + await user.type(nameInput, c); + expect(nameInput).toHaveValue(progressive); + } + + // Submitted is blank so far + const submittedSection = screen.getByRole("region", { + name: /submitted data/i, + }); + const submittedName = + within(submittedSection).getByTestId("submitted-name"); + const submittedList = + within(submittedSection).getByTestId("submitted-list"); + expect(submittedName).toHaveTextContent("Name:"); + expect(within(submittedList).queryAllByRole("listitem")).toHaveLength(0); + + // 2) Add two friends -> Example1, Example2 + const addFriendBtn = screen.getByRole("button", { name: /add friend/i }); + await user.click(addFriendBtn); + await user.click(addFriendBtn); + + const friend1 = screen.getByTestId("friend-Example1"); + const friend2 = screen.getByTestId("friend-Example2"); + expect(within(friend1).getByText("Example1")).toBeInTheDocument(); + expect(within(friend2).getByText("Example2")).toBeInTheDocument(); + + // 3) Type friend names with per-keystroke assertions + const friend1Input = within(friend1).getByRole("textbox", { + name: "Friend name for Example1", + }); + const friend2Input = within(friend2).getByRole("textbox", { + name: "Friend name for Example2", + }); + + const friend1Name = "Example1"; + const friend2Name = "Example2"; + + let p = ""; + for (const c of friend1Name) { + p += c; + await user.type(friend1Input, c); + expect(friend1Input).toHaveValue(p); + } + + p = ""; + for (const c of friend2Name) { + p += c; + await user.type(friend2Input, c); + expect(friend2Input).toHaveValue(p); + } + + // Still nothing committed + expect(submittedName).toHaveTextContent("Name:"); + expect(within(submittedList).queryAllByRole("listitem")).toHaveLength(0); + + // 4) Remove Example2 + await user.click( + within(friend2).getByRole("button", { name: /remove friend/i }), + ); + expect(screen.queryByTestId("friend-Example2")).not.toBeInTheDocument(); + + // 5) Submit -> committed data reflects Example0 + Example1 only + await user.click(screen.getByRole("button", { name: /submit/i })); + + // Form retained its values + expect(nameInput).toHaveValue("Example0"); + expect(friend1Input).toHaveValue("Example1"); + expect(screen.queryByTestId("friend-Example2")).not.toBeInTheDocument(); + + // Committed view updated + expect(submittedName).toHaveTextContent("Name: Example0"); + const itemsAfterSubmit = within(submittedList).getAllByRole("listitem"); + expect(itemsAfterSubmit).toHaveLength(1); + expect(itemsAfterSubmit[0]).toHaveTextContent( + "Id: Example1 Name: Example1", + ); + + // 6) Change name and resubmit + await user.clear(nameInput); + const newName = "anotherExample0"; + let q = ""; + for (const c of newName) { + q += c; + await user.type(nameInput, c); + expect(nameInput).toHaveValue(q); + } + await user.click(screen.getByRole("button", { name: /submit/i })); + + expect(submittedName).toHaveTextContent(`Name: ${newName}`); + const itemsAfterSecondSubmit = + within(submittedList).getAllByRole("listitem"); + expect(itemsAfterSecondSubmit).toHaveLength(1); + expect(itemsAfterSecondSubmit[0]).toHaveTextContent( + "Id: Example1 Name: Example1", + ); + }); +}); diff --git a/packages/react/vitest.config.js b/packages/react/vitest.config.js index 9713f14..5d263c8 100644 --- a/packages/react/vitest.config.js +++ b/packages/react/vitest.config.js @@ -1,9 +1,12 @@ import { defineConfig } from "vitest/config"; +import react from "@vitejs/plugin-react"; export default defineConfig({ + plugins: [react()], test: { coverage: { provider: "istanbul", }, + environment: "jsdom", }, });