Added LDO package

main
jaxoncreed 2 years ago
parent e0520c0d08
commit 3961705934
  1. 11
      .eslintrc
  2. 356
      package-lock.json
  3. 2
      packages/cli/.eslintrc
  4. 5
      packages/cli/package.json
  5. 16
      packages/cli/src/build.ts
  6. 14
      packages/cli/src/init.ts
  7. 2
      packages/cli/src/templates/shapeTypes.ejs
  8. 2
      packages/demo-react/package.json
  9. 3
      packages/demo-react/src/App.tsx
  10. 3
      packages/demo-react/src/BlurTextInput.tsx
  11. 7
      packages/demo-react/src/Layout.tsx
  12. 3
      packages/demo-react/src/Profile.tsx
  13. 2
      packages/demo-react/src/ldo/solidProfile.context.ts
  14. 2
      packages/demo-react/src/ldo/solidProfile.schema.ts
  15. 4
      packages/demo-react/src/ldo/solidProfile.shapeTypes.ts
  16. 2
      packages/demo-react/src/ldo/solidProfile.typings.ts
  17. 3
      packages/ldo/.eslintrc
  18. 77
      packages/ldo/example/example.ts
  19. 26
      packages/ldo/example/ldo/foafProfile.context.ts
  20. 93
      packages/ldo/example/ldo/foafProfile.schema.ts
  21. 19
      packages/ldo/example/ldo/foafProfile.shapeTypes.ts
  22. 33
      packages/ldo/example/ldo/foafProfile.typings.ts
  23. 15
      packages/ldo/example/shapes/foafProfile.shex
  24. 5
      packages/ldo/jest.config.js
  25. 47
      packages/ldo/package.json
  26. 112
      packages/ldo/src/LdoBuilder.ts
  27. 23
      packages/ldo/src/LdoDataset.ts
  28. 23
      packages/ldo/src/LdoDatasetFactory.ts
  29. 13
      packages/ldo/src/ShapeType.ts
  30. 19
      packages/ldo/src/createLdoDataset.ts
  31. 52
      packages/ldo/src/datasetConverters.ts
  32. 9
      packages/ldo/src/index.ts
  33. 109
      packages/ldo/src/methods.ts
  34. 32
      packages/ldo/src/parseRdf.ts
  35. 70
      packages/ldo/src/util.ts
  36. 7
      packages/ldo/tsconfig.build.json
  37. 2
      packages/solid-react/.eslintrc
  38. 7
      packages/solid-react/package.json
  39. 8
      packages/solid-react/src/LdoContext.ts
  40. 15
      packages/solid-react/src/LdoProvider.tsx
  41. 10
      packages/solid-react/src/SolidAuthProvider.ts
  42. 4
      packages/solid-react/src/document/DocumentStore.ts
  43. 2
      packages/solid-react/src/document/FetchableDocument.ts
  44. 14
      packages/solid-react/src/document/accessRules/AccessRules.ts
  45. 8
      packages/solid-react/src/document/accessRules/AccessRulesStore.ts
  46. 2
      packages/solid-react/src/document/errors/DocumentError.ts
  47. 2
      packages/solid-react/src/document/errors/DocumentFetchError.ts
  48. 16
      packages/solid-react/src/document/resource/Resource.ts
  49. 5
      packages/solid-react/src/document/resource/binaryResource/BinaryResource.ts
  50. 6
      packages/solid-react/src/document/resource/binaryResource/BinaryResourceStore.ts
  51. 22
      packages/solid-react/src/document/resource/dataResource/DataResource.ts
  52. 6
      packages/solid-react/src/document/resource/dataResource/DataResourceStore.ts
  53. 15
      packages/solid-react/src/document/resource/dataResource/containerResource/ContainerResource.ts
  54. 14
      packages/solid-react/src/document/resource/dataResource/containerResource/ContainerResourceStore.ts
  55. 7
      packages/solid-react/src/documentHooks/useAccessRules.ts
  56. 3
      packages/solid-react/src/documentHooks/useBinaryResource.ts
  57. 5
      packages/solid-react/src/documentHooks/useContainerResource.ts
  58. 3
      packages/solid-react/src/documentHooks/useDataResource.ts
  59. 8
      packages/solid-react/src/documentHooks/useDocument.ts
  60. 2
      packages/solid-react/src/ldo/solid.context.ts
  61. 2
      packages/solid-react/src/ldo/solid.schema.ts
  62. 4
      packages/solid-react/src/ldo/solid.shapeTypes.ts
  63. 4
      packages/solid-react/src/ldo/solid.typings.ts
  64. 20
      packages/solid-react/src/ldoHooks/helpers/TrackingProxyContext.ts
  65. 11
      packages/solid-react/src/ldoHooks/helpers/UpdateManager.ts
  66. 19
      packages/solid-react/src/ldoHooks/useSubject.ts
  67. 42
      packages/solid-react/src/useLdo.ts
  68. 10
      packages/solid-react/src/util/changesToSparqlUpdate.ts
  69. 9
      packages/solid-react/src/util/createGlobalHook.tsx
  70. 13
      packages/solid-react/src/util/splitChangesByGraph.ts

@ -18,6 +18,15 @@
}
},
"rules": {
"no-unused-vars": "off"
"no-unused-vars": "off",
"@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
]
}
}

356
package-lock.json generated

@ -5166,6 +5166,10 @@
"resolved": "packages/demo-react",
"link": true
},
"node_modules/@ldo/ldo": {
"resolved": "packages/ldo",
"link": true
},
"node_modules/@ldo/solid-react": {
"resolved": "packages/solid-react",
"link": true
@ -7590,14 +7594,14 @@
"integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA=="
},
"node_modules/@types/q": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",
"integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ=="
"version": "1.5.6",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.6.tgz",
"integrity": "sha512-IKjZ8RjTSwD4/YG+2gtj7BPFRB/lNbWKTiSj3M7U/TD2B7HfYCxvp2Zz6xA2WIY7pAuL1QOUPw8gQRbUrrq4fQ=="
},
"node_modules/@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
"version": "6.9.8",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz",
"integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg=="
},
"node_modules/@types/range-parser": {
"version": "1.2.4",
@ -9808,9 +9812,9 @@
}
},
"node_modules/cacache/node_modules/glob": {
"version": "10.3.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz",
"integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==",
"version": "10.3.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz",
"integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==",
"dev": true,
"dependencies": {
"foreground-child": "^3.1.0",
@ -9981,9 +9985,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001524",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz",
"integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==",
"version": "1.0.30001525",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz",
"integrity": "sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q==",
"funding": [
{
"type": "opencollective",
@ -12237,9 +12241,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.4.505",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz",
"integrity": "sha512-0A50eL5BCCKdxig2SsCXhpuztnB9PfUgRMojj5tMvt8O54lbwz3t6wNgnpiTRosw5QjlJB7ixhVyeg8daLQwSQ=="
"version": "1.4.506",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.506.tgz",
"integrity": "sha512-xxGct4GPAKSRlrLBtJxJFYy74W11zX6PO9GyHgl/U+2s3Dp0ZEwAklDfNHXOWcvH7zWMpsmgbR0ggEuaYAVvHA=="
},
"node_modules/emitter-component": {
"version": "1.1.1",
@ -14678,9 +14682,9 @@
}
},
"node_modules/fraction.js": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.1.tgz",
"integrity": "sha512-nx0cki48JBA6ThPeUpeKCNpdhEl/9bRS+dAEYnRUod+Z1jhFfC3K/mBLorZZntqHM+GTH3/dkkpfoT3QITYe7g==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz",
"integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==",
"engines": {
"node": "*"
},
@ -16742,14 +16746,13 @@
}
},
"node_modules/iterator.prototype": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.0.tgz",
"integrity": "sha512-rjuhAk1AJ1fssphHD0IFV6TWL40CwRZ53FrztKx43yk2v6rguBYsY4Bj1VU4HmoMmKwZUlx7mfnhDf9cOp4YTw==",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.1.tgz",
"integrity": "sha512-9E+nePc8C9cnQldmNl6bgpTY6zI4OPRZd97fhJ/iVZ1GifIUDVV5F6x1nEDqpe8KaMEZGT4xgrwKQDxXnjOIZQ==",
"dependencies": {
"define-properties": "^1.1.4",
"get-intrinsic": "^1.1.3",
"define-properties": "^1.2.0",
"get-intrinsic": "^1.2.1",
"has-symbols": "^1.0.3",
"has-tostringtag": "^1.0.0",
"reflect.getprototypeof": "^1.0.3"
}
},
@ -18208,34 +18211,6 @@
"shell-quote": "^1.7.3"
}
},
"node_modules/ldo": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/ldo/-/ldo-1.0.3.tgz",
"integrity": "sha512-pW0rKzA/uEKHLO/hq3x1+35EcAygGFsPlMBN3wZJQJVP4L5nV2Psx9VLqgl/cv8kmTFeuPmh4i5u1CogGwyaAw==",
"dependencies": {
"@rdfjs/data-model": "^1.2.0",
"buffer": "^6.0.3",
"jsonld-dataset-proxy": "^1.2.1",
"n3": "^1.16.2",
"o-dataset-pack": "^0.2.11",
"readable-stream": "^4.3.0"
}
},
"node_modules/ldo/node_modules/readable-stream": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz",
"integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==",
"dependencies": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
"events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/lerna": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/lerna/-/lerna-7.2.0.tgz",
@ -25163,9 +25138,9 @@
}
},
"node_modules/read-package-json/node_modules/glob": {
"version": "10.3.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz",
"integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==",
"version": "10.3.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz",
"integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==",
"dev": true,
"dependencies": {
"foreground-child": "^3.1.0",
@ -25528,14 +25503,14 @@
}
},
"node_modules/reflect.getprototypeof": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.3.tgz",
"integrity": "sha512-TTAOZpkJ2YLxl7mVHWrNo3iDMEkYlva/kgFcXndqMgbo/AZUmmavEkdXV+hXtE4P8xdyEKRzalaFqZVuwIk/Nw==",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
"integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==",
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
"es-abstract": "^1.20.4",
"get-intrinsic": "^1.1.1",
"define-properties": "^1.2.0",
"es-abstract": "^1.22.1",
"get-intrinsic": "^1.2.1",
"globalthis": "^1.0.3",
"which-builtin-type": "^1.1.3"
},
@ -30093,7 +30068,7 @@
"@types/ejs": "^3.1.1",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.0.3",
"@types/shexj": "^2.1.4",
"@types/shexj": "2.1.4",
"copyfiles": "^2.4.1",
"jest": "^27.4.2",
"rimraf": "^3.0.2",
@ -30458,15 +30433,112 @@
"node": ">= 6"
}
},
"packages/ldo": {
"name": "@ldo/ldo",
"version": "0.0.0",
"license": "MIT",
"dependencies": {
"@rdfjs/data-model": "^1.2.0",
"buffer": "^6.0.3",
"jsonld-dataset-proxy": "^1.2.1",
"n3": "^1.16.2",
"o-dataset-pack": "^0.2.11",
"readable-stream": "^4.3.0"
},
"devDependencies": {
"@rdfjs/types": "^1.1.0",
"@types/jest": "^27.0.3",
"@types/jsonld": "^1.5.6",
"@types/n3": "^1.10.4",
"@types/readable-stream": "^2.3.13",
"@types/shexj": "2.1.4",
"cross-fetch": "^3.1.5",
"jest": "^27.4.5",
"ts-jest": "^27.1.2",
"ts-node": "^10.4.0"
}
},
"packages/ldo/node_modules/readable-stream": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz",
"integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==",
"dependencies": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
"events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"packages/ldo/node_modules/ts-jest": {
"version": "27.1.5",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz",
"integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==",
"dev": true,
"dependencies": {
"bs-logger": "0.x",
"fast-json-stable-stringify": "2.x",
"jest-util": "^27.0.0",
"json5": "2.x",
"lodash.memoize": "4.x",
"make-error": "1.x",
"semver": "7.x",
"yargs-parser": "20.x"
},
"bin": {
"ts-jest": "cli.js"
},
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
},
"peerDependencies": {
"@babel/core": ">=7.0.0-beta.0 <8",
"@types/jest": "^27.0.0",
"babel-jest": ">=27.0.0 <28",
"jest": "^27.0.0",
"typescript": ">=3.8 <5.0"
},
"peerDependenciesMeta": {
"@babel/core": {
"optional": true
},
"@types/jest": {
"optional": true
},
"babel-jest": {
"optional": true
},
"esbuild": {
"optional": true
}
}
},
"packages/ldo/node_modules/typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"dev": true,
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"packages/solid-react": {
"name": "@ldo/solid-react",
"version": "0.0.0",
"license": "MIT",
"dependencies": {
"@inrupt/solid-client": "^1.29.0",
"@ldo/ldo": "^0.0.0",
"cross-fetch": "^3.1.6",
"jsonld-dataset-proxy": "^1.2.3",
"ldo": "^1.0.3",
"o-dataset-pack": "^0.2.14",
"solid-authn-react-native": "^2.0.3",
"stream": "^0.0.2"
@ -30480,7 +30552,7 @@
"@types/jest": "^29.0.3",
"@types/jsonld": "^1.5.8",
"@types/n3": "^1.10.4",
"@types/shexj": "^2.1.4",
"@types/shexj": "2.1.4",
"ts-jest": "^29.0.2"
}
},
@ -35452,7 +35524,7 @@
"@types/ejs": "^3.1.1",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.0.3",
"@types/shexj": "^2.1.4",
"@types/shexj": "2.1.4",
"child-process-promise": "^2.2.1",
"commander": "^9.3.0",
"copyfiles": "^2.4.1",
@ -35684,6 +35756,64 @@
}
}
},
"@ldo/ldo": {
"version": "file:packages/ldo",
"requires": {
"@rdfjs/data-model": "^1.2.0",
"@rdfjs/types": "^1.1.0",
"@types/jest": "^27.0.3",
"@types/jsonld": "^1.5.6",
"@types/n3": "^1.10.4",
"@types/readable-stream": "^2.3.13",
"@types/shexj": "2.1.4",
"buffer": "^6.0.3",
"cross-fetch": "^3.1.5",
"jest": "^27.4.5",
"jsonld-dataset-proxy": "^1.2.1",
"n3": "^1.16.2",
"o-dataset-pack": "^0.2.11",
"readable-stream": "^4.3.0",
"ts-jest": "^27.1.2",
"ts-node": "^10.4.0"
},
"dependencies": {
"readable-stream": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz",
"integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==",
"requires": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
"events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
}
},
"ts-jest": {
"version": "27.1.5",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz",
"integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==",
"dev": true,
"requires": {
"bs-logger": "0.x",
"fast-json-stable-stringify": "2.x",
"jest-util": "^27.0.0",
"json5": "2.x",
"lodash.memoize": "4.x",
"make-error": "1.x",
"semver": "7.x",
"yargs-parser": "20.x"
}
},
"typescript": {
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"dev": true,
"peer": true
}
}
},
"@ldo/solid-react": {
"version": "file:packages/solid-react",
"requires": {
@ -35692,14 +35822,14 @@
"@babel/preset-typescript": "^7.22.11",
"@inrupt/solid-client": "^1.29.0",
"@ldo/cli": "^0.0.0",
"@ldo/ldo": "^0.0.0",
"@rdfjs/types": "^1.1.0",
"@types/jest": "^29.0.3",
"@types/jsonld": "^1.5.8",
"@types/n3": "^1.10.4",
"@types/shexj": "^2.1.4",
"@types/shexj": "2.1.4",
"cross-fetch": "^3.1.6",
"jsonld-dataset-proxy": "^1.2.3",
"ldo": "^1.0.3",
"o-dataset-pack": "^0.2.14",
"solid-authn-react-native": "^2.0.3",
"stream": "^0.0.2",
@ -38529,14 +38659,14 @@
"integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA=="
},
"@types/q": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz",
"integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ=="
"version": "1.5.6",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.6.tgz",
"integrity": "sha512-IKjZ8RjTSwD4/YG+2gtj7BPFRB/lNbWKTiSj3M7U/TD2B7HfYCxvp2Zz6xA2WIY7pAuL1QOUPw8gQRbUrrq4fQ=="
},
"@types/qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
"integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw=="
"version": "6.9.8",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.8.tgz",
"integrity": "sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg=="
},
"@types/range-parser": {
"version": "1.2.4",
@ -40214,9 +40344,9 @@
}
},
"glob": {
"version": "10.3.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz",
"integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==",
"version": "10.3.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz",
"integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==",
"dev": true,
"requires": {
"foreground-child": "^3.1.0",
@ -40340,9 +40470,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001524",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz",
"integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA=="
"version": "1.0.30001525",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz",
"integrity": "sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q=="
},
"canonicalize": {
"version": "1.0.8",
@ -41978,9 +42108,9 @@
}
},
"electron-to-chromium": {
"version": "1.4.505",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz",
"integrity": "sha512-0A50eL5BCCKdxig2SsCXhpuztnB9PfUgRMojj5tMvt8O54lbwz3t6wNgnpiTRosw5QjlJB7ixhVyeg8daLQwSQ=="
"version": "1.4.506",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.506.tgz",
"integrity": "sha512-xxGct4GPAKSRlrLBtJxJFYy74W11zX6PO9GyHgl/U+2s3Dp0ZEwAklDfNHXOWcvH7zWMpsmgbR0ggEuaYAVvHA=="
},
"emitter-component": {
"version": "1.1.1",
@ -43760,9 +43890,9 @@
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
},
"fraction.js": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.1.tgz",
"integrity": "sha512-nx0cki48JBA6ThPeUpeKCNpdhEl/9bRS+dAEYnRUod+Z1jhFfC3K/mBLorZZntqHM+GTH3/dkkpfoT3QITYe7g=="
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz",
"integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q=="
},
"freeport-async": {
"version": "2.0.0",
@ -45247,14 +45377,13 @@
}
},
"iterator.prototype": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.0.tgz",
"integrity": "sha512-rjuhAk1AJ1fssphHD0IFV6TWL40CwRZ53FrztKx43yk2v6rguBYsY4Bj1VU4HmoMmKwZUlx7mfnhDf9cOp4YTw==",
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.1.tgz",
"integrity": "sha512-9E+nePc8C9cnQldmNl6bgpTY6zI4OPRZd97fhJ/iVZ1GifIUDVV5F6x1nEDqpe8KaMEZGT4xgrwKQDxXnjOIZQ==",
"requires": {
"define-properties": "^1.1.4",
"get-intrinsic": "^1.1.3",
"define-properties": "^1.2.0",
"get-intrinsic": "^1.2.1",
"has-symbols": "^1.0.3",
"has-tostringtag": "^1.0.0",
"reflect.getprototypeof": "^1.0.3"
}
},
@ -46405,33 +46534,6 @@
"shell-quote": "^1.7.3"
}
},
"ldo": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/ldo/-/ldo-1.0.3.tgz",
"integrity": "sha512-pW0rKzA/uEKHLO/hq3x1+35EcAygGFsPlMBN3wZJQJVP4L5nV2Psx9VLqgl/cv8kmTFeuPmh4i5u1CogGwyaAw==",
"requires": {
"@rdfjs/data-model": "^1.2.0",
"buffer": "^6.0.3",
"jsonld-dataset-proxy": "^1.2.1",
"n3": "^1.16.2",
"o-dataset-pack": "^0.2.11",
"readable-stream": "^4.3.0"
},
"dependencies": {
"readable-stream": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz",
"integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==",
"requires": {
"abort-controller": "^3.0.0",
"buffer": "^6.0.3",
"events": "^3.3.0",
"process": "^0.11.10",
"string_decoder": "^1.3.0"
}
}
}
},
"lerna": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/lerna/-/lerna-7.2.0.tgz",
@ -51541,9 +51643,9 @@
}
},
"glob": {
"version": "10.3.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz",
"integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==",
"version": "10.3.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz",
"integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==",
"dev": true,
"requires": {
"foreground-child": "^3.1.0",
@ -51834,14 +51936,14 @@
}
},
"reflect.getprototypeof": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.3.tgz",
"integrity": "sha512-TTAOZpkJ2YLxl7mVHWrNo3iDMEkYlva/kgFcXndqMgbo/AZUmmavEkdXV+hXtE4P8xdyEKRzalaFqZVuwIk/Nw==",
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz",
"integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.4",
"es-abstract": "^1.20.4",
"get-intrinsic": "^1.1.1",
"define-properties": "^1.2.0",
"es-abstract": "^1.22.1",
"get-intrinsic": "^1.2.1",
"globalthis": "^1.0.3",
"which-builtin-type": "^1.1.3"
}

@ -1,3 +1,3 @@
{
"extends": ["../../eslintrc"]
"extends": ["../../.eslintrc"]
}

@ -19,7 +19,8 @@
"test": "jest --coverage",
"test:watch": "jest --watch",
"prepublishOnly": "npm run test && npm run build",
"postinstall": "npm run build"
"postinstall": "npm run build",
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern"
},
"repository": {
"type": "git",
@ -36,7 +37,7 @@
"@types/ejs": "^3.1.1",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.0.3",
"@types/shexj": "^2.1.4",
"@types/shexj": "2.1.4",
"copyfiles": "^2.4.1",
"jest": "^27.4.2",
"rimraf": "^3.0.2",

@ -1,6 +1,6 @@
import fs from "fs-extra";
import path from "path";
import { Schema } from "shexj";
import type { Schema } from "shexj";
import parser from "@shexjs/parser";
import shexjToTypeAndContext from "shexj2typeandcontext";
import { renderFile } from "ejs";
@ -20,7 +20,7 @@ export async function build(options: BuildOptions) {
});
// Filter out non-shex documents
const shexFiles = shapeDir.filter(
(file) => file.isFile() && file.name.endsWith(".shex")
(file) => file.isFile() && file.name.endsWith(".shex"),
);
// Prepare new folder by clearing/and/or creating it
if (fs.existsSync(options.output)) {
@ -35,7 +35,7 @@ export async function build(options: BuildOptions) {
// Get the content of each document
const shexC = await fs.promises.readFile(
path.join(options.input, file.name),
"utf8"
"utf8",
);
// Convert to ShexJ
const schema: Schema = parser
@ -53,17 +53,17 @@ export async function build(options: BuildOptions) {
fileName,
schema: JSON.stringify(schema, null, 2),
context: JSON.stringify(context, null, 2),
}
},
);
// Save conversion to document
await fs.promises.writeFile(
path.join(options.output, `${fileName}.${templateName}.ts`),
await prettier.format(finalContent, { parser: "typescript" })
await prettier.format(finalContent, { parser: "typescript" }),
);
}
)
},
),
);
})
}),
);
load.stop();
}

@ -28,7 +28,7 @@ export async function init(initOptions: InitOptions) {
for (let i = 0; i < POTENTIAL_PARENT_DIRECTORIES.length; i++) {
if (
allDirectories.some(
(dir) => dir.name === POTENTIAL_PARENT_DIRECTORIES[i]
(dir) => dir.name === POTENTIAL_PARENT_DIRECTORIES[i],
)
) {
parentDirectory = POTENTIAL_PARENT_DIRECTORIES[i];
@ -41,25 +41,25 @@ export async function init(initOptions: InitOptions) {
const shapesFolderPath = path.join(parentDirectory, DEFAULT_SHAPES_FOLDER);
await fs.promises.mkdir(shapesFolderPath);
const defaultShapePaths = await fs.promises.readdir(
path.join(__dirname, "./templates/defaultShapes")
path.join(__dirname, "./templates/defaultShapes"),
);
await Promise.all(
defaultShapePaths.map(async (shapePath) => {
const shapeContent = await renderFile(
path.join(__dirname, "./templates/defaultShapes", shapePath),
{}
{},
);
await fs.promises.writeFile(
path.join(shapesFolderPath, `${path.parse(shapePath).name}.shex`),
shapeContent
shapeContent,
);
})
}),
);
// Add build script
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const packageJson: any = JSON.parse(
(await fs.promises.readFile("./package.json")).toString()
(await fs.promises.readFile("./package.json")).toString(),
);
if (!packageJson.scripts) {
packageJson.scripts = {};
@ -70,7 +70,7 @@ export async function init(initOptions: InitOptions) {
] = `ldo build --input ${shapesFolderPath} --output ${ldoFolder}`;
await fs.promises.writeFile(
"./package.json",
JSON.stringify(packageJson, null, 2)
JSON.stringify(packageJson, null, 2),
);
// Build LDO

@ -1,4 +1,4 @@
import { ShapeType } from "ldo";
import { ShapeType } from "@ldo/ldo";
import { <%- fileName %>Schema } from "./<%- fileName %>.schema";
import { <%- fileName %>Context } from "./<%- fileName %>.context";
import {

@ -13,7 +13,7 @@
"start": "craco start",
"build": "craco build",
"eject": "react-scripts eject",
"lint": "eslint src/** --fix",
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern",
"build:ldo": "ldo build --input src/shapes --output src/ldo"
},
"eslintConfig": {

@ -1,4 +1,5 @@
import React, { FunctionComponent } from "react";
import type { FunctionComponent } from "react";
import React from "react";
import Profile from "./Profile";
import { SolidAuthProvider, LdoProvider } from "@ldo/solid-react";
import { fetch } from "solid-authn-react-native";

@ -1,4 +1,5 @@
import React, { FunctionComponent, useState } from "react";
import type { FunctionComponent } from "react";
import React, { useState } from "react";
interface BlurTextInputProps {
value: string;

@ -1,8 +1,5 @@
import React, {
FunctionComponent,
PropsWithChildren,
useCallback,
} from "react";
import type { FunctionComponent, PropsWithChildren } from "react";
import React, { useCallback } from "react";
import { useSolidAuth } from "@ldo/solid-react";
const Layout: FunctionComponent<PropsWithChildren> = ({ children }) => {

@ -1,4 +1,5 @@
import React, { FunctionComponent } from "react";
import type { FunctionComponent } from "react";
import React from "react";
import { SolidProfileShapeShapeType } from "./ldo/solidProfile.shapeTypes";
import BlurTextInput from "./BlurTextInput";
import {

@ -1,4 +1,4 @@
import { ContextDefinition } from "jsonld";
import type { ContextDefinition } from "jsonld";
/**
* =============================================================================

@ -1,4 +1,4 @@
import { Schema } from "shexj";
import type { Schema } from "shexj";
/**
* =============================================================================

@ -1,7 +1,7 @@
import { ShapeType } from "ldo";
import type { ShapeType } from "@ldo/ldo";
import { solidProfileSchema } from "./solidProfile.schema";
import { solidProfileContext } from "./solidProfile.context";
import {
import type {
SolidProfileShape,
AddressShape,
EmailShape,

@ -1,4 +1,4 @@
import { ContextDefinition } from "jsonld";
import type { ContextDefinition } from "jsonld";
/**
* =============================================================================

@ -0,0 +1,3 @@
{
"extends": ["../../.eslintrc"]
}

@ -0,0 +1,77 @@
import { parseRdf, startTransaction, toSparqlUpdate, toTurtle } from "../lib";
import { FoafProfileShapeType } from "./ldo/foafProfile.shapeTypes";
async function run() {
const rawTurtle = `
<#me> a <http://xmlns.com/foaf/0.1/Person>;
<http://xmlns.com/foaf/0.1/name> "Jane Doe".
`;
/**
* Step 1: Convert Raw RDF into a Linked Data Object
*/
const ldoDataset = await parseRdf(rawTurtle, {
baseIRI: "https://solidweb.me/jane_doe/profile/card",
});
// Create a linked data object by telling the dataset the type and subject of
// the object
const janeProfile = ldoDataset
// Tells the LDO dataset that we're looking for a FoafProfile
.usingType(FoafProfileShapeType)
// Says the subject of the FoafProfile
.fromSubject("https://solidweb.me/jane_doe/profile/card#me");
/**
* Step 2: Manipulate the Linked Data Object
*/
// Logs "Jane Doe"
console.log(janeProfile.name);
// Logs "Person"
console.log(janeProfile.type);
// Logs 0
console.log(janeProfile.knows?.length);
// Begins a transaction that tracks your changes
startTransaction(janeProfile);
janeProfile.name = "Jane Smith";
janeProfile.knows?.push({
"@id": "https://solidweb.me/john_smith/profile/card#me",
type: {
"@id": "Person",
},
name: "John Smith",
knows: [janeProfile],
});
// Logs "Jane Smith"
console.log(janeProfile.name);
// Logs "John Smith"
console.log(janeProfile.knows?.[0].name);
// Logs "Jane Smith"
console.log(janeProfile.knows?.[0].knows?.[0].name);
/**
* Step 3: Convert it back to RDF
*/
// Logs:
// <https://solidweb.me/jane_doe/profile/card#me> a <http://xmlns.com/foaf/0.1/Person>;
// <http://xmlns.com/foaf/0.1/name> "Jane Smith";
// <http://xmlns.com/foaf/0.1/knows> <https://solidweb.me/john_smith/profile/card#me>.
// <https://solidweb.me/john_smith/profile/card#me> a <http://xmlns.com/foaf/0.1/Person>;
// <http://xmlns.com/foaf/0.1/name> "John Smith";
// <http://xmlns.com/foaf/0.1/knows> <https://solidweb.me/jane_doe/profile/card#me>.
console.log(await toTurtle(janeProfile));
// Logs:
// DELETE DATA {
// <https://solidweb.me/jane_doe/profile/card#me> <http://xmlns.com/foaf/0.1/name> "Jane Doe" .
// };
// INSERT DATA {
// <https://solidweb.me/jane_doe/profile/card#me> <http://xmlns.com/foaf/0.1/name> "Jane Smith" .
// <https://solidweb.me/jane_doe/profile/card#me> <http://xmlns.com/foaf/0.1/knows> <https://solidweb.me/john_smith/profile/card#me> .
// <https://solidweb.me/john_smith/profile/card#me> <http://xmlns.com/foaf/0.1/name> "John Smith" .
// <https://solidweb.me/john_smith/profile/card#me> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
// <https://solidweb.me/john_smith/profile/card#me> <http://xmlns.com/foaf/0.1/knows> <https://solidweb.me/jane_doe/profile/card#me> .
// }
console.log(await toSparqlUpdate(janeProfile));
}
run();

@ -0,0 +1,26 @@
import { ContextDefinition } from "jsonld";
/**
* =============================================================================
* foafProfileContext: JSONLD Context for foafProfile
* =============================================================================
*/
export const foafProfileContext: ContextDefinition = {
type: {
"@id": "@type",
},
Person: "http://xmlns.com/foaf/0.1/Person",
name: {
"@id": "http://xmlns.com/foaf/0.1/name",
"@type": "http://www.w3.org/2001/XMLSchema#string",
},
img: {
"@id": "http://xmlns.com/foaf/0.1/img",
"@type": "http://www.w3.org/2001/XMLSchema#string",
},
knows: {
"@id": "http://xmlns.com/foaf/0.1/knows",
"@type": "@id",
"@container": "@set",
},
};

@ -0,0 +1,93 @@
import { Schema } from "shexj";
/**
* =============================================================================
* foafProfileSchema: ShexJ Schema for foafProfile
* =============================================================================
*/
export const foafProfileSchema: Schema = {
type: "Schema",
shapes: [
{
id: "https://example.com/FoafProfile",
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://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://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: "Define a person's name.",
},
},
],
},
{
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://xmlns.com/foaf/0.1/knows",
valueExpr: "https://example.com/FoafProfile",
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"],
},
],
};

@ -0,0 +1,19 @@
import { ShapeType } from "../../lib";
import { foafProfileSchema } from "./foafProfile.schema";
import { foafProfileContext } from "./foafProfile.context";
import { FoafProfile } from "./foafProfile.typings";
/**
* =============================================================================
* LDO ShapeTypes foafProfile
* =============================================================================
*/
/**
* FoafProfile ShapeType
*/
export const FoafProfileShapeType: ShapeType<FoafProfile> = {
schema: foafProfileSchema,
shape: "https://example.com/FoafProfile",
context: foafProfileContext,
};

@ -0,0 +1,33 @@
import { ContextDefinition } from "jsonld";
/**
* =============================================================================
* Typescript Typings for foafProfile
* =============================================================================
*/
/**
* FoafProfile Type
*/
export interface FoafProfile {
"@id"?: string;
"@context"?: ContextDefinition;
/**
* Defines the node as a Person (from foaf)
*/
type: {
"@id": "Person";
};
/**
* Define a person's name.
*/
name?: string;
/**
* Photo link but in string form
*/
img?: string;
/**
* A list of WebIds for all the people this user knows.
*/
knows?: FoafProfile[];
}

@ -0,0 +1,15 @@
PREFIX ex: <https://example.com/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
ex:FoafProfile EXTRA a {
a [ foaf:Person ]
// rdfs:comment "Defines the node as a Person (from foaf)" ;
foaf:name xsd:string ?
// rdfs:comment "Define a person's name." ;
foaf:img xsd:string ?
// rdfs:comment "Photo link but in string form" ;
foaf:knows @ex:FoafProfile *
// rdfs:comment "A list of WebIds for all the people this user knows." ;
}

@ -0,0 +1,5 @@
const sharedConfig = require('../../jest.config.js');
module.exports = {
...sharedConfig,
'rootDir': './',
}

@ -0,0 +1,47 @@
{
"name": "@ldo/ldo",
"version": "0.0.0",
"description": "",
"main": "dist/index.js",
"scripts": {
"example": "ts-node ./example/example.ts",
"build": "tsc --project tsconfig.build.json",
"test": "jest --coverage",
"test:watch": "jest --watch --coverage",
"prepublishOnly": "npm run test && npm run build",
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern"
},
"repository": {
"type": "git",
"url": "git+https://github.com/o-development/ldo.git"
},
"author": "Jackson Morgan",
"license": "MIT",
"bugs": {
"url": "https://github.com/o-development/ldo/issues"
},
"homepage": "https://github.com/o-development/ldo#readme",
"devDependencies": {
"@rdfjs/types": "^1.1.0",
"@types/jest": "^27.0.3",
"@types/jsonld": "^1.5.6",
"@types/n3": "^1.10.4",
"@types/readable-stream": "^2.3.13",
"@types/shexj": "2.1.4",
"cross-fetch": "^3.1.5",
"jest": "^27.4.5",
"ts-jest": "^27.1.2",
"ts-node": "^10.4.0"
},
"dependencies": {
"@rdfjs/data-model": "^1.2.0",
"buffer": "^6.0.3",
"jsonld-dataset-proxy": "^1.2.1",
"n3": "^1.16.2",
"o-dataset-pack": "^0.2.11",
"readable-stream": "^4.3.0"
},
"overrides": {
"readable-stream": "^4.3.0"
}
}

@ -0,0 +1,112 @@
import type {
GraphType,
JsonldDatasetProxyBuilder,
QuadMatch,
SubjectType,
LanguageOrdering,
} from "jsonld-dataset-proxy";
import type { ShapeType } from "./ShapeType";
import type { LdoBase } from "./util";
import { normalizeNodeName, normalizeNodeNames } from "./util";
/**
* A wrapper around Jsonld Dataset Proxy Builder with a slightly more friendly
* user experience that doesn't require the use of rdfjs datatypes.
*/
export class LdoBuilder<Type extends LdoBase> {
private jsonldDatasetProxyBuilder: JsonldDatasetProxyBuilder;
private shapeType: ShapeType<Type>;
constructor(
jsonldDatasetProxyBuilder: JsonldDatasetProxyBuilder,
shapeType: ShapeType<Type>,
) {
this.jsonldDatasetProxyBuilder = jsonldDatasetProxyBuilder;
this.shapeType = shapeType;
}
/**
* Designates that all Linked Data Objects created should write to the
* specified graphs
*/
write(...graphs: (GraphType | string)[]): LdoBuilder<Type> {
return new LdoBuilder(
this.jsonldDatasetProxyBuilder.write(...normalizeNodeNames(graphs)),
this.shapeType,
);
}
/**
* Sets the order of language preferences for Language Strings. Acceptable
* values as EITF language tags, "@none" and "@other"
*/
setLanguagePreferences(
...languageOrdering: LanguageOrdering
): LdoBuilder<Type> {
return new LdoBuilder(
this.jsonldDatasetProxyBuilder.setLanguagePreferences(
...languageOrdering,
),
this.shapeType,
);
}
/**
* Creates a Linked Data Object that matches the given subject
* @param subject The node to match
*/
fromSubject(subject: SubjectType | string): Type {
return this.jsonldDatasetProxyBuilder.fromSubject<Type>(
normalizeNodeName(subject),
);
}
/**
* Matches Subjects to provided predicates, objects, and graphs. Returns a
* JSON LD Dataset that can be read an modified.
* @param predicate The predicate to match
* @param object The object to match
* @param graph The graph to match
*/
matchSubject(
predicate: QuadMatch[1] | string,
object?: QuadMatch[2] | string,
graph?: QuadMatch[3] | string,
): Type[] {
return this.jsonldDatasetProxyBuilder.matchSubject<Type>(
predicate != undefined ? normalizeNodeName(predicate) : undefined,
object != undefined ? normalizeNodeName(object) : undefined,
graph != undefined ? normalizeNodeName(graph) : undefined,
);
}
/**
* Matches Objects to provided subjects, predicates, and graphs. Returns a
* collection of Linked Data Objects that can be read an modified.
* @param subject The subject to match
* @param predicate The predicate to match
* @param graph The graph to match
*/
matchObject(
subject?: QuadMatch[0] | string,
predicate?: QuadMatch[1] | string,
graph?: QuadMatch[3] | string,
): Type[] {
return this.jsonldDatasetProxyBuilder.matchObject<Type>(
subject != undefined ? normalizeNodeName(subject) : undefined,
predicate != undefined ? normalizeNodeName(predicate) : undefined,
graph != undefined ? normalizeNodeName(graph) : undefined,
);
}
/**
* Takes a given object and places it in the dataset while returning a Linked
* Data Object representing the object.
*
* @param inputData Initial Data
* @param graph Optional graph to save this data to
*/
fromJson(inputData: Type): Type {
return this.jsonldDatasetProxyBuilder.fromJson<Type>(inputData);
}
}

@ -0,0 +1,23 @@
import type { Quad } from "@rdfjs/types";
import jsonldDatasetProxy from "jsonld-dataset-proxy";
import { WrapperSubscribableDataset } from "o-dataset-pack";
import { LdoBuilder } from "./LdoBuilder";
import type { ShapeType } from "./ShapeType";
import type { LdoBase } from "./util";
/**
* Utility for building a linked data object
*/
export class LdoDataset extends WrapperSubscribableDataset<Quad> {
/**
* Gets a builder for a given type
* @param shapeType A ShapeType
* @returns A builder for the given type
*/
public usingType<Type extends LdoBase>(
shapeType: ShapeType<Type>,
): LdoBuilder<Type> {
const proxyBuilder = jsonldDatasetProxy(this, shapeType.context);
return new LdoBuilder(proxyBuilder, shapeType);
}
}

@ -0,0 +1,23 @@
import type { DatasetFactory, Dataset, Quad } from "@rdfjs/types";
import { LdoDataset } from "./LdoDataset";
/**
* A DatasetFactory that creates an ExtendedDataset given a DatasetCoreFactory.
*/
export class LdoDatasetFactory implements DatasetFactory<Quad, Quad> {
private datasetFactory: DatasetFactory<Quad, Quad>;
constructor(datasetFactory: DatasetFactory<Quad, Quad>) {
this.datasetFactory = datasetFactory;
}
dataset(quads?: Dataset<Quad, Quad> | Quad[]): LdoDataset {
return new LdoDataset(
this.datasetFactory,
quads
? Array.isArray(quads)
? this.datasetFactory.dataset(quads)
: quads
: undefined,
);
}
}

@ -0,0 +1,13 @@
import type { ContextDefinition } from "jsonld";
import type { Schema } from "shexj";
import type { LdoBase } from "./util";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ShapeType<Type extends LdoBase> = {
schema: Schema;
shape: string;
context: ContextDefinition;
// This field is optional. It's main point is to allow the typescript parser to
// understand that this shape type is of a specific type.
exampleData?: Type;
};

@ -0,0 +1,19 @@
import type { Dataset, DatasetFactory, Quad } from "@rdfjs/types";
import { createDataset } from "o-dataset-pack";
import { LdoDatasetFactory } from "./LdoDatasetFactory";
export function createLdoDatasetFactory() {
const datasetFactory: DatasetFactory<Quad> = {
dataset: (quads?: Dataset<Quad> | Quad[]): Dataset<Quad> => {
return createDataset(quads);
},
};
return new LdoDatasetFactory(datasetFactory);
}
export function createLdoDataset(
initialDataset?: Dataset<Quad, Quad> | Quad[],
) {
const ldoDatasetFactory = createLdoDatasetFactory();
return ldoDatasetFactory.dataset(initialDataset);
}

@ -0,0 +1,52 @@
import type { Dataset } from "@rdfjs/types";
import type { WriterOptions } from "n3";
import { Writer } from "n3";
// import SerializerJsonld from "@rdfjs/serializer-jsonld";
// import { Readable } from "readable-stream";
export async function datasetToString(
dataset: Dataset,
options: WriterOptions,
): Promise<string> {
return new Promise<string>((resolve, reject) => {
const writer = new Writer(options);
for (const quad of dataset) {
writer.addQuad(quad);
}
writer.end(async (error, parsedString: string) => {
/* istanbul ignore if */
if (error) {
return reject(error);
}
return resolve(parsedString);
});
});
}
// export async function datasetToJsonLd(
// dataset: Dataset,
// context: ContextDefinition
// ): Promise<JsonLdDocument> {
// return new Promise((resolve, reject) => {
// const serializerJsonld = new SerializerJsonld();
// const input = new Readable({
// objectMode: true,
// read: () => {
// dataset.forEach((quad) => {
// input.push(quad);
// });
// input.push(null);
// },
// });
// const output = serializerJsonld.import(input);
// output.on("data", (jsonld) => {
// resolve(jsonld);
// });
// /* istanbul ignore next */
// output.on("error", (err) => {
// /* istanbul ignore next */
// reject(err);
// });
// });
// }

@ -0,0 +1,9 @@
export * from "./parseRdf";
export * from "./ShapeType";
export * from "./methods";
export * from "./LdoDataset";
export * from "./LdoBuilder";
export * from "./createLdoDataset";
import type { LdoBase as LdoBaseImport } from "./util";
export type LdoBase = LdoBaseImport;
export { datasetToString } from "./datasetConverters";

@ -0,0 +1,109 @@
import type { Dataset } from "@rdfjs/types";
import type { JsonLdDocument } from "jsonld";
import type { GraphType, InteractOptions } from "jsonld-dataset-proxy";
import {
getProxyFromObject,
_getUnderlyingDataset,
_proxyContext,
write as writeDependency,
} from "jsonld-dataset-proxy";
import type { Quad, WriterOptions } from "n3";
import type { DatasetChanges, SubscribableDataset } from "o-dataset-pack";
import { datasetToString } from "./datasetConverters";
import type { LdoBase } from "./util";
import {
canDatasetStartTransaction,
getTransactionalDatasetFromLdo,
normalizeNodeNames,
} from "./util";
export {
graphOf,
languagesOf,
setLanguagePreferences,
} from "jsonld-dataset-proxy";
export function write(...graphs: (GraphType | string)[]): InteractOptions {
return writeDependency(...normalizeNodeNames(graphs));
}
/**
* Begins a transaction for the given linked data object
* @param ldo
*/
export function startTransaction(ldo: LdoBase): void {
const proxy = getProxyFromObject(ldo);
const dataset = proxy[_getUnderlyingDataset];
if (!canDatasetStartTransaction(dataset)) {
throw new Error("Object is not transactable.");
}
proxy[_proxyContext] = proxy[_proxyContext].duplicate({
dataset: (dataset as SubscribableDataset<Quad>).startTransaction(),
state: { parentDataset: dataset },
});
}
/**
* Ends a transaction and commits the
* @param ldo
*/
export function commitTransaction(ldo: LdoBase): void {
const [dataset, proxy] = getTransactionalDatasetFromLdo(ldo);
dataset.commit();
proxy[_proxyContext] = proxy[_proxyContext].duplicate({
dataset: proxy[_proxyContext].state
.parentDataset as SubscribableDataset<Quad>,
});
}
export function transactionChanges(ldo: LdoBase): DatasetChanges {
const [dataset] = getTransactionalDatasetFromLdo(ldo);
return dataset.getChanges();
}
export function getDataset(ldo: LdoBase): Dataset {
const proxy = getProxyFromObject(ldo);
return proxy[_getUnderlyingDataset];
}
export async function toSparqlUpdate(ldo: LdoBase): Promise<string> {
const [dataset] = getTransactionalDatasetFromLdo(ldo);
const changes = dataset.getChanges();
let output = "";
if (changes.removed) {
output += `DELETE DATA { ${await datasetToString(changes.removed, {
format: "N-Triples",
})} }`;
}
if (changes.added && changes.removed) {
output += "; ";
}
if (changes.added) {
output += `INSERT DATA { ${await datasetToString(changes.added, {
format: "N-Triples",
})} }`;
}
return output.replaceAll("\n", " ");
}
export async function serialize(
ldo: LdoBase,
options: WriterOptions,
): Promise<string> {
const dataset = getProxyFromObject(ldo)[_getUnderlyingDataset];
return datasetToString(dataset, options);
}
export async function toTurtle(ldo: LdoBase): Promise<string> {
const dataset = getProxyFromObject(ldo)[_getUnderlyingDataset];
return datasetToString(dataset, {});
}
export async function toJsonLd(_ldo: LdoBase): Promise<JsonLdDocument> {
throw new Error("Not Implemented");
}
export async function toNTriples(ldo: LdoBase): Promise<string> {
const dataset = getProxyFromObject(ldo)[_getUnderlyingDataset];
return datasetToString(dataset, { format: "N-Triples" });
}

@ -0,0 +1,32 @@
import type { Dataset } from "@rdfjs/types";
import type { JsonLdDocument } from "jsonld";
import type { ParserOptions } from "n3";
import { createDatasetFromSerializedInput } from "o-dataset-pack";
import { createLdoDataset, createLdoDatasetFactory } from "./createLdoDataset";
import type { LdoDataset } from "./LdoDataset";
export async function parseRdf(
data: string | JsonLdDocument | Dataset,
parserOptions?: ParserOptions,
): Promise<LdoDataset> {
const ldoDatasetFactory = createLdoDatasetFactory();
if (typeof data === "string") {
// Input data is serialized
return await createDatasetFromSerializedInput(
ldoDatasetFactory,
data,
parserOptions,
);
} else if (typeof (data as Dataset).add === "function") {
// Input data is a dataset
return createLdoDataset(data as Dataset);
} else {
return await createDatasetFromSerializedInput(
ldoDatasetFactory,
JSON.stringify(data),
{
format: "application/json-ld",
},
);
}
}

@ -0,0 +1,70 @@
import { namedNode } from "@rdfjs/data-model";
import type { Dataset } from "@rdfjs/types";
import type {
ArrayProxy,
GraphType,
ObjectType,
PredicateType,
SubjectProxy,
SubjectType,
} from "jsonld-dataset-proxy";
import {
getProxyFromObject,
_getUnderlyingDataset,
_proxyContext,
} from "jsonld-dataset-proxy";
import type { Quad } from "n3";
import type { SubscribableDataset, TransactionalDataset } from "o-dataset-pack";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type LdoBase = Record<string, any>;
/**
* Converts a node/string into just a node
* @param input A Node or string
* @returns A node
*/
export function normalizeNodeName<
NodeType extends SubjectType | PredicateType | ObjectType | GraphType,
>(input: NodeType | string): NodeType {
return (typeof input === "string" ? namedNode(input) : input) as NodeType;
}
/**
* Converts an array of nodes/strings into an array of nodes
* @param inputs An array of nodes/strings
* @returns An array of nodes
*/
export function normalizeNodeNames<
NodeType extends SubjectType | PredicateType | ObjectType | GraphType,
>(inputs: (NodeType | string)[]): NodeType[] {
return inputs.map((input) => normalizeNodeName<NodeType>(input));
}
export function canDatasetStartTransaction(
dataset: Dataset,
): dataset is SubscribableDataset<Quad> {
return (
typeof (dataset as SubscribableDataset).startTransaction === "function"
);
}
export function isTransactionalDataset(
dataset: Dataset,
): dataset is TransactionalDataset<Quad> {
return typeof (dataset as TransactionalDataset).commit === "function";
}
export function getTransactionalDatasetFromLdo(
ldo: LdoBase,
): [TransactionalDataset<Quad>, SubjectProxy | ArrayProxy] {
const proxy = getProxyFromObject(ldo);
const dataset = proxy[_getUnderlyingDataset];
if (
!isTransactionalDataset(dataset) ||
!proxy[_proxyContext].state.parentDataset
) {
throw new Error("Object is not currently in a transaction");
}
return [dataset, proxy];
}

@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": ["./src"]
}

@ -1,3 +1,3 @@
{
"extends": ["../../eslintrc"]
"extends": ["../../.eslintrc"]
}

@ -9,7 +9,8 @@
"test": "jest --coverage",
"test:watch": "jest --watch",
"prepublishOnly": "npm run test && npm run build",
"build:ldo": "ldo build --input src/shapes --output src/ldo"
"build:ldo": "ldo build --input src/shapes --output src/ldo",
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern"
},
"repository": {
"type": "git",
@ -30,14 +31,14 @@
"@types/jest": "^29.0.3",
"@types/jsonld": "^1.5.8",
"@types/n3": "^1.10.4",
"@types/shexj": "^2.1.4",
"@types/shexj": "2.1.4",
"ts-jest": "^29.0.2"
},
"dependencies": {
"@inrupt/solid-client": "^1.29.0",
"@ldo/ldo": "^0.0.0",
"cross-fetch": "^3.1.6",
"jsonld-dataset-proxy": "^1.2.3",
"ldo": "^1.0.3",
"o-dataset-pack": "^0.2.14",
"solid-authn-react-native": "^2.0.3",
"stream": "^0.0.2"

@ -1,8 +1,8 @@
import { createContext, useContext } from "react";
import { BinaryResourceStoreDependencies } from "./document/resource/binaryResource/BinaryResourceStore";
import { DataResourceStoreDependencies } from "./document/resource/dataResource/DataResourceStore";
import { AccessRulesStoreDependencies } from "./document/accessRules/AccessRulesStore";
import { ContainerResourceStoreDependencies } from "./document/resource/dataResource/containerResource/ContainerResourceStore";
import type { BinaryResourceStoreDependencies } from "./document/resource/binaryResource/BinaryResourceStore";
import type { DataResourceStoreDependencies } from "./document/resource/dataResource/DataResourceStore";
import type { AccessRulesStoreDependencies } from "./document/accessRules/AccessRulesStore";
import type { ContainerResourceStoreDependencies } from "./document/resource/dataResource/containerResource/ContainerResourceStore";
export interface LdoContextData
extends BinaryResourceStoreDependencies,

@ -1,18 +1,15 @@
import React, {
FunctionComponent,
PropsWithChildren,
useEffect,
useMemo,
} from "react";
import type { FunctionComponent, PropsWithChildren } from "react";
import React, { useEffect, useMemo } from "react";
import crossFetch from "cross-fetch";
import { createLdoDataset } from "ldo";
import { LdoContextData, LdoContextProvider } from "./LdoContext";
import { createLdoDataset } from "@ldo/ldo";
import type { LdoContextData } from "./LdoContext";
import { LdoContextProvider } from "./LdoContext";
import { UpdateManager } from "./ldoHooks/helpers/UpdateManager";
import { BinaryResourceStore } from "./document/resource/binaryResource/BinaryResourceStore";
import { DataResourceStore } from "./document/resource/dataResource/DataResourceStore";
import { ContainerResourceStore } from "./document/resource/dataResource/containerResource/ContainerResourceStore";
import { AccessRulesStore } from "./document/accessRules/AccessRulesStore";
import { Dataset } from "@rdfjs/types";
import type { Dataset } from "@rdfjs/types";
export interface LdoProviderProps extends PropsWithChildren {
fetch?: typeof fetch;

@ -1,6 +1,6 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import type { ISessionInfo } from "solid-authn-react-native";
import {
ISessionInfo,
handleIncomingRedirect,
login as libraryLogin,
getDefaultSession,
@ -24,7 +24,7 @@ interface AuthGlobalHookReturn {
function useAuthGlobalHookFunc(): AuthGlobalHookReturn {
const [session, setSession] = useState<ISessionInfo>(
getDefaultSession().info
getDefaultSession().info,
);
const [ranInitialAuthCheck, setRanInitialAuthCheck] = useState(false);
@ -42,7 +42,7 @@ function useAuthGlobalHookFunc(): AuthGlobalHookReturn {
window.history.replaceState(
{},
"",
window.localStorage.getItem(PRE_REDIRECT_URI)
window.localStorage.getItem(PRE_REDIRECT_URI),
);
window.localStorage.removeItem(PRE_REDIRECT_URI);
@ -60,7 +60,7 @@ function useAuthGlobalHookFunc(): AuthGlobalHookReturn {
});
setSession({ ...getDefaultSession().info });
},
[]
[],
);
const logout = useCallback(async () => {
@ -87,7 +87,7 @@ function useAuthGlobalHookFunc(): AuthGlobalHookReturn {
ranInitialAuthCheck,
fetch: libraryFetch,
}),
[login, logout, ranInitialAuthCheck, runInitialAuthCheck, session, signUp]
[login, logout, ranInitialAuthCheck, runInitialAuthCheck, session, signUp],
);
}

@ -1,4 +1,4 @@
import { FetchableDocument } from "./FetchableDocument";
import type { FetchableDocument } from "./FetchableDocument";
// This may eventually have fields
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@ -7,7 +7,7 @@ export interface DocumentStoreDependencies {}
export abstract class DocumentStore<
DocumentType extends FetchableDocument,
Initializer,
Dependencies extends DocumentStoreDependencies
Dependencies extends DocumentStoreDependencies,
> {
protected documentMap: Map<Initializer, DocumentType>;
protected dependencies: Dependencies;

@ -1,5 +1,5 @@
import EventEmitter from "events";
import { DocumentError } from "./errors/DocumentError";
import type { DocumentError } from "./errors/DocumentError";
export interface FetchableDocumentDependencies {
onDocumentError?: (error: DocumentError) => void;

@ -1,12 +1,8 @@
import {
universalAccess,
AccessModes as IAccessModes,
} from "@inrupt/solid-client";
import {
FetchableDocument,
FetchableDocumentDependencies,
} from "../FetchableDocument";
import { Resource } from "../resource/Resource";
import type { AccessModes as IAccessModes } from "@inrupt/solid-client";
import { universalAccess } from "@inrupt/solid-client";
import type { FetchableDocumentDependencies } from "../FetchableDocument";
import { FetchableDocument } from "../FetchableDocument";
import type { Resource } from "../resource/Resource";
import { DocumentError } from "../errors/DocumentError";
export type AccessModes = IAccessModes;

@ -1,6 +1,8 @@
import { DocumentStore, DocumentStoreDependencies } from "../DocumentStore";
import { Resource } from "../resource/Resource";
import { AccessRules, AccessRulesDependencies } from "./AccessRules";
import type { DocumentStoreDependencies } from "../DocumentStore";
import { DocumentStore } from "../DocumentStore";
import type { Resource } from "../resource/Resource";
import type { AccessRulesDependencies } from "./AccessRules";
import { AccessRules } from "./AccessRules";
export interface AccessRulesStoreDependencies
extends DocumentStoreDependencies,

@ -1,4 +1,4 @@
import { FetchableDocument } from "../FetchableDocument";
import type { FetchableDocument } from "../FetchableDocument";
export class DocumentError extends Error {
public readonly document: FetchableDocument;

@ -1,4 +1,4 @@
import { FetchableDocument } from "../FetchableDocument";
import type { FetchableDocument } from "../FetchableDocument";
import { DocumentError } from "./DocumentError";
export class DocumentFetchError extends DocumentError {

@ -1,11 +1,9 @@
import {
FetchableDocument,
FetchableDocumentDependencies,
} from "../FetchableDocument";
import { AccessRulesStore } from "../accessRules/AccessRulesStore";
import type { FetchableDocumentDependencies } from "../FetchableDocument";
import { FetchableDocument } from "../FetchableDocument";
import type { AccessRulesStore } from "../accessRules/AccessRulesStore";
import { DocumentFetchError } from "../errors/DocumentFetchError";
import { ContainerResource } from "./dataResource/containerResource/ContainerResource";
import { ContainerResourceStore } from "./dataResource/containerResource/ContainerResourceStore";
import type { ContainerResource } from "./dataResource/containerResource/ContainerResource";
import type { ContainerResourceStore } from "./dataResource/containerResource/ContainerResourceStore";
export interface ResourceDependencies extends FetchableDocumentDependencies {
fetch: typeof fetch;
@ -71,8 +69,8 @@ export abstract class Resource extends FetchableDocument {
new DocumentFetchError(
this,
response.status,
`Could not delete ${this.uri}`
)
`Could not delete ${this.uri}`,
),
);
}

@ -1,5 +1,6 @@
import { DocumentError } from "../../errors/DocumentError";
import { Resource, ResourceDependencies } from "../Resource";
import type { DocumentError } from "../../errors/DocumentError";
import type { ResourceDependencies } from "../Resource";
import { Resource } from "../Resource";
export declare type BinaryResourceDependencies = ResourceDependencies;

@ -1,5 +1,7 @@
import { DocumentStore, DocumentStoreDependencies } from "../../DocumentStore";
import { BinaryResource, BinaryResourceDependencies } from "./BinaryResource";
import type { DocumentStoreDependencies } from "../../DocumentStore";
import { DocumentStore } from "../../DocumentStore";
import type { BinaryResourceDependencies } from "./BinaryResource";
import { BinaryResource } from "./BinaryResource";
export interface BinaryResourceStoreDependencies
extends DocumentStoreDependencies,

@ -1,12 +1,14 @@
import { LdoDataset, parseRdf } from "ldo";
import { Resource, ResourceDependencies } from "../Resource";
import type { LdoDataset } from "@ldo/ldo";
import { parseRdf } from "@ldo/ldo";
import type { ResourceDependencies } from "../Resource";
import { Resource } from "../Resource";
import { DocumentFetchError } from "../../errors/DocumentFetchError";
import { DocumentError } from "../../errors/DocumentError";
import { namedNode, quad as createQuad } from "@rdfjs/data-model";
import { DatasetChanges } from "o-dataset-pack";
import { Quad } from "@rdfjs/types";
import type { DatasetChanges } from "o-dataset-pack";
import type { Quad } from "@rdfjs/types";
import { changesToSparqlUpdate } from "../../../util/changesToSparqlUpdate";
import { UpdateManager } from "../../../ldoHooks/helpers/UpdateManager";
import type { UpdateManager } from "../../../ldoHooks/helpers/UpdateManager";
export interface DataResourceDependencies extends ResourceDependencies {
dataset: LdoDataset;
@ -56,7 +58,7 @@ export class DataResource extends Resource {
return new DocumentFetchError(
this,
response.status,
`Error fetching resource ${this.uri}`
`Error fetching resource ${this.uri}`,
);
}
// Parse the incoming turtle into a dataset
@ -80,7 +82,7 @@ export class DataResource extends Resource {
// Add the triples from the fetched item
loadedDataset.forEach((quad) => {
transactionalDataset.add(
createQuad(quad.subject, quad.predicate, quad.object, graphNode)
createQuad(quad.subject, quad.predicate, quad.object, graphNode),
);
});
const changes = transactionalDataset.getChanges();
@ -90,7 +92,7 @@ export class DataResource extends Resource {
}
async update(
changes: DatasetChanges<Quad>
changes: DatasetChanges<Quad>,
): Promise<DocumentError | undefined> {
this.beginWrite();
// Convert changes to transactional Dataset
@ -117,8 +119,8 @@ export class DataResource extends Resource {
new DocumentFetchError(
this,
response.status,
`Problem writing to ${this.uri}`
)
`Problem writing to ${this.uri}`,
),
);
return;
}

@ -1,5 +1,7 @@
import { DocumentStore, DocumentStoreDependencies } from "../../DocumentStore";
import { DataResource, DataResourceDependencies } from "./DataResource";
import type { DocumentStoreDependencies } from "../../DocumentStore";
import { DocumentStore } from "../../DocumentStore";
import type { DataResourceDependencies } from "./DataResource";
import { DataResource } from "./DataResource";
export interface DataResourceStoreDependencies
extends DocumentStoreDependencies,

@ -1,8 +1,9 @@
import { ContainerShapeType } from "../../../../ldo/solid.shapeTypes";
import { Resource } from "../../Resource";
import { BinaryResourceStore } from "../../binaryResource/BinaryResourceStore";
import { DataResource, DataResourceDependencies } from "../DataResource";
import { DataResourceStore } from "../DataResourceStore";
import type { Resource } from "../../Resource";
import type { BinaryResourceStore } from "../../binaryResource/BinaryResourceStore";
import type { DataResourceDependencies } from "../DataResource";
import { DataResource } from "../DataResource";
import type { DataResourceStore } from "../DataResourceStore";
export interface ContainerResourceDependencies
extends DataResourceDependencies {
@ -55,16 +56,16 @@ export class ContainerResource extends DataResource {
if (resourceData["@id"]) {
if (resourceData.type?.some((type) => type["@id"] === "Container")) {
resourcesToAdd.push(
this.containerResourceStore.get(resourceData["@id"])
this.containerResourceStore.get(resourceData["@id"]),
);
} else {
if (resourceData["@id"].endsWith(".ttl")) {
resourcesToAdd.push(
this.dataResourceStore.get(resourceData["@id"])
this.dataResourceStore.get(resourceData["@id"]),
);
} else {
resourcesToAdd.push(
this.binaryResourceStore.get(resourceData["@id"])
this.binaryResourceStore.get(resourceData["@id"]),
);
}
}

@ -1,12 +1,8 @@
import {
DocumentStore,
DocumentStoreDependencies,
} from "../../../DocumentStore";
import { Resource } from "../../Resource";
import {
ContainerResource,
ContainerResourceDependencies,
} from "./ContainerResource";
import type { DocumentStoreDependencies } from "../../../DocumentStore";
import { DocumentStore } from "../../../DocumentStore";
import type { Resource } from "../../Resource";
import type { ContainerResourceDependencies } from "./ContainerResource";
import { ContainerResource } from "./ContainerResource";
export interface ContainerResourceStoreDependencies
extends ContainerResourceDependencies,

@ -1,11 +1,12 @@
import { useMemo } from "react";
import { useLdoContext } from "../LdoContext";
import { UseDocumentOptions, useDocument } from "./useDocument";
import { Resource } from "../document/resource/Resource";
import type { UseDocumentOptions } from "./useDocument";
import { useDocument } from "./useDocument";
import type { Resource } from "../document/resource/Resource";
export function useAccessRules(
resource: string | Resource,
options?: UseDocumentOptions
options?: UseDocumentOptions,
) {
const { dataResourceStore, accessRulesStore } = useLdoContext();
const realResource = useMemo(() => {

@ -1,5 +1,6 @@
import { useLdoContext } from "../LdoContext";
import { UseDocumentOptions, useDocument } from "./useDocument";
import type { UseDocumentOptions } from "./useDocument";
import { useDocument } from "./useDocument";
export function useBinaryResource(uri: string, options?: UseDocumentOptions) {
const { binaryResourceStore } = useLdoContext();

@ -1,9 +1,10 @@
import { useLdoContext } from "../LdoContext";
import { UseDocumentOptions, useDocument } from "./useDocument";
import type { UseDocumentOptions } from "./useDocument";
import { useDocument } from "./useDocument";
export function useContainerResource(
uri: string,
options?: UseDocumentOptions
options?: UseDocumentOptions,
) {
const { containerResourceStore } = useLdoContext();
return useDocument(uri, containerResourceStore, options);

@ -1,5 +1,6 @@
import { useLdoContext } from "../LdoContext";
import { UseDocumentOptions, useDocument } from "./useDocument";
import type { UseDocumentOptions } from "./useDocument";
import { useDocument } from "./useDocument";
export function useDataResource(uri: string, options?: UseDocumentOptions) {
const { dataResourceStore } = useLdoContext();

@ -1,9 +1,9 @@
import { useEffect, useMemo } from "react";
import {
import type {
DocumentStore,
DocumentStoreDependencies,
} from "../document/DocumentStore";
import { FetchableDocument } from "../document/FetchableDocument";
import type { FetchableDocument } from "../document/FetchableDocument";
import { useForceUpdate } from "../util/useForceReload";
export interface UseDocumentOptions {
@ -12,7 +12,7 @@ export interface UseDocumentOptions {
export function useDocument<
DocumentType extends FetchableDocument,
Initializer
Initializer,
>(
initializer: Initializer,
documentStore: DocumentStore<
@ -20,7 +20,7 @@ export function useDocument<
Initializer,
DocumentStoreDependencies
>,
options?: UseDocumentOptions
options?: UseDocumentOptions,
) {
const document = useMemo(() => {
return documentStore.get(initializer);

@ -1,4 +1,4 @@
import { ContextDefinition } from "jsonld";
import type { ContextDefinition } from "jsonld";
/**
* =============================================================================

@ -1,4 +1,4 @@
import { Schema } from "shexj";
import type { Schema } from "shexj";
/**
* =============================================================================

@ -1,7 +1,7 @@
import { ShapeType } from "ldo";
import type { ShapeType } from "@ldo/ldo";
import { solidSchema } from "./solid.schema";
import { solidContext } from "./solid.context";
import { Container, Resource } from "./solid.typings";
import type { Container, Resource } from "./solid.typings";
/**
* =============================================================================

@ -1,4 +1,4 @@
import { ContextDefinition } from "jsonld";
import type { ContextDefinition } from "jsonld";
/**
* =============================================================================
@ -30,7 +30,7 @@ export interface Container {
/**
* Defines a Solid Resource
*/
contains?: (Resource | Container)[];
contains?: Resource[];
/**
* ?
*/

@ -1,10 +1,10 @@
import {
import type {
ArrayProxyTarget,
ProxyContext,
SubjectProxyTarget,
ProxyContextOptions,
} from "jsonld-dataset-proxy";
import { UpdateManager } from "./UpdateManager";
import { ProxyContext } from "jsonld-dataset-proxy";
import type { UpdateManager } from "./UpdateManager";
import { namedNode } from "@rdfjs/data-model";
export class TrackingProxyContext extends ProxyContext {
@ -14,7 +14,7 @@ export class TrackingProxyContext extends ProxyContext {
constructor(
options: ProxyContextOptions,
updateManager: UpdateManager,
listener: () => void
listener: () => void,
) {
super(options);
this.updateManager = updateManager;
@ -27,7 +27,7 @@ export class TrackingProxyContext extends ProxyContext {
const newGetFunction: ProxyHandler<SubjectProxyTarget>["get"] = (
target: SubjectProxyTarget,
key: string | symbol,
receiver
receiver,
) => {
const subject = target["@id"];
if (typeof key === "symbol") {
@ -35,13 +35,13 @@ export class TrackingProxyContext extends ProxyContext {
} else if (key === "@id") {
this.updateManager.registerListener(
[subject, null, null],
this.listener
this.listener,
);
} else if (!this.contextUtil.isArray(key)) {
const predicate = namedNode(this.contextUtil.keyToIri(key));
this.updateManager.registerListener(
[subject, predicate, null],
this.listener
this.listener,
);
}
return oldGetFunction && oldGetFunction(target, key, receiver);
@ -49,7 +49,7 @@ export class TrackingProxyContext extends ProxyContext {
baseHandler.get = newGetFunction;
baseHandler.set = () => {
console.warn(
"You've attempted to set a value on a Linked Data Object from the useSubject, useMatchingSubject, or useMatchingObject hooks. These linked data objects should only be used to render data, not modify it. To modify data, use the `changeData` function."
"You've attempted to set a value on a Linked Data Object from the useSubject, useMatchingSubject, or useMatchingObject hooks. These linked data objects should only be used to render data, not modify it. To modify data, use the `changeData` function.",
);
return true;
};
@ -62,12 +62,12 @@ export class TrackingProxyContext extends ProxyContext {
const newGetFunction: ProxyHandler<ArrayProxyTarget>["get"] = (
target: ArrayProxyTarget,
key: string | symbol,
receiver
receiver,
) => {
if (qualifiedArrayMethods.has(key)) {
this.updateManager.registerListener(
[target[0][0], target[0][1], target[0][2]],
this.listener
this.listener,
);
}
return oldGetFunction && oldGetFunction(target, key, receiver);

@ -1,12 +1,13 @@
import { DatasetChanges, createDataset } from "o-dataset-pack";
import {
import type { DatasetChanges } from "o-dataset-pack";
import { createDataset } from "o-dataset-pack";
import type {
QuadMatch,
SubjectType,
PredicateType,
ObjectType,
nodeToString,
} from "jsonld-dataset-proxy";
import { Quad } from "@rdfjs/types";
import { nodeToString } from "jsonld-dataset-proxy";
import type { Quad } from "@rdfjs/types";
export type TripleMatch = [QuadMatch[0], QuadMatch[1], QuadMatch[2]];
@ -16,7 +17,7 @@ export class UpdateManager {
private tripleMatchToHash(tripleMatch: TripleMatch): string {
return `${nodeToString(tripleMatch[0])}${nodeToString(
tripleMatch[1]
tripleMatch[1],
)}${nodeToString(tripleMatch[2])}`;
}

@ -1,10 +1,7 @@
import {
ContextUtil,
JsonldDatasetProxyBuilder,
SubjectType,
} from "jsonld-dataset-proxy";
import { LdoBuilder, ShapeType } from "ldo";
import { LdoBase } from "ldo/dist/util";
import type { SubjectType } from "jsonld-dataset-proxy";
import { ContextUtil, JsonldDatasetProxyBuilder } from "jsonld-dataset-proxy";
import type { ShapeType, LdoBase } from "@ldo/ldo";
import { LdoBuilder } from "@ldo/ldo";
import { useLdoContext } from "../LdoContext";
import { useCallback, useEffect, useMemo, useState } from "react";
import { TrackingProxyContext } from "./helpers/TrackingProxyContext";
@ -12,14 +9,14 @@ import { defaultGraph } from "@rdfjs/data-model";
export function useSubject<Type extends LdoBase>(
shapeType: ShapeType<Type>,
subject: string | SubjectType
subject: string | SubjectType,
): [Type, undefined] | [undefined, Error] {
const { dataset, updateManager } = useLdoContext();
const [forceUpdateCounter, setForceUpdateCounter] = useState(0);
const forceUpdate = useCallback(
() => setForceUpdateCounter((val) => val + 1),
[setForceUpdateCounter]
[setForceUpdateCounter],
);
// The main linked data object
@ -34,11 +31,11 @@ export function useSubject<Type extends LdoBase>(
languageOrdering: ["none", "en", "other"],
},
updateManager,
forceUpdate
forceUpdate,
);
const builder = new LdoBuilder(
new JsonldDatasetProxyBuilder(proxyContext),
shapeType
shapeType,
);
return builder.fromSubject(subject);
}, [

@ -1,22 +1,16 @@
import { useCallback, useMemo } from "react";
import { useLdoContext } from "./LdoContext";
import {
LdoDataset,
ShapeType,
startTransaction,
transactionChanges,
write,
} from "ldo";
import type { LdoDataset, ShapeType, LdoBase } from "@ldo/ldo";
import { startTransaction, transactionChanges, write } from "@ldo/ldo";
import { splitChangesByGraph } from "./util/splitChangesByGraph";
import { LdoBase } from "ldo/dist/util";
import { Resource } from "./document/resource/Resource";
import { DataResource } from "./document/resource/dataResource/DataResource";
import { BinaryResource } from "./document/resource/binaryResource/BinaryResource";
import { ContainerResource } from "./document/resource/dataResource/containerResource/ContainerResource";
import { AccessRules } from "./document/accessRules/AccessRules";
import { SubjectType } from "jsonld-dataset-proxy";
import { DatasetChanges } from "o-dataset-pack";
import { Quad } from "@rdfjs/types";
import type { Resource } from "./document/resource/Resource";
import type { DataResource } from "./document/resource/dataResource/DataResource";
import type { BinaryResource } from "./document/resource/binaryResource/BinaryResource";
import type { ContainerResource } from "./document/resource/dataResource/containerResource/ContainerResource";
import type { AccessRules } from "./document/accessRules/AccessRules";
import type { SubjectType } from "jsonld-dataset-proxy";
import type { DatasetChanges } from "o-dataset-pack";
import type { Quad } from "@rdfjs/types";
export interface UseLdoReturn {
changeData<Type extends LdoBase>(input: Type, ...resources: Resource[]): Type;
@ -48,14 +42,14 @@ export function useLdo(): UseLdoReturn {
<Type extends LdoBase>(input: Type, ...resources: Resource[]) => {
// Clone the input and set a graph
const [transactionLdo] = write(...resources.map((r) => r.uri)).usingCopy(
input
input,
);
// Start a transaction with the input
startTransaction(transactionLdo);
// Return
return transactionLdo;
},
[dataset]
[dataset],
);
/**
* Begins tracking changes to eventually commit for a new subject
@ -73,7 +67,7 @@ export function useLdo(): UseLdoReturn {
startTransaction(linkedDataObject);
return linkedDataObject;
},
[]
[],
);
/**
* Commits the transaction to the global dataset, syncing all subscribing
@ -83,7 +77,7 @@ export function useLdo(): UseLdoReturn {
async (input: LdoBase) => {
const changes = transactionChanges(input);
const changesByGraph = splitChangesByGraph(
changes as DatasetChanges<Quad>
changes as DatasetChanges<Quad>,
);
// Make queries
await Promise.all(
@ -94,11 +88,11 @@ export function useLdo(): UseLdoReturn {
}
const resource = dataResourceStore.get(graph.value);
await resource.update(datasetChanges);
}
)
},
),
);
},
[dataset, fetch]
[dataset, fetch],
);
// Returns the values
return useMemo(
@ -112,6 +106,6 @@ export function useLdo(): UseLdoReturn {
getContainerResource: (uri) => containerResourceStore.get(uri),
getAccessRules: (resource) => accessRulesStore.get(resource),
}),
[dataset, changeData, commitData]
[dataset, changeData, commitData],
);
}

@ -1,6 +1,6 @@
import { DatasetChanges } from "o-dataset-pack";
import { datasetToString } from "ldo/dist/datasetConverters";
import { Quad } from "@rdfjs/types";
import type { DatasetChanges } from "o-dataset-pack";
import { datasetToString } from "@ldo/ldo";
import type { Quad } from "@rdfjs/types";
import { quad as createQuad } from "@rdfjs/data-model";
// TODO: This file is a clone from the one in the base ldo library. This resused
@ -9,7 +9,7 @@ export async function changesToSparqlUpdate(changes: DatasetChanges<Quad>) {
let output = "";
if (changes.removed) {
const removedTriples = changes.removed.map((quad) =>
createQuad(quad.subject, quad.predicate, quad.object)
createQuad(quad.subject, quad.predicate, quad.object),
);
output += `DELETE DATA { ${await datasetToString(removedTriples, {
format: "N-Triples",
@ -20,7 +20,7 @@ export async function changesToSparqlUpdate(changes: DatasetChanges<Quad>) {
}
if (changes.added) {
const addedTriples = changes.added.map((quad) =>
createQuad(quad.subject, quad.predicate, quad.object)
createQuad(quad.subject, quad.predicate, quad.object),
);
output += `INSERT DATA { ${await datasetToString(addedTriples, {
format: "N-Triples",

@ -1,10 +1,5 @@
import React, {
createContext,
FunctionComponent,
useContext,
Context,
PropsWithChildren,
} from "react";
import type { FunctionComponent, Context, PropsWithChildren } from "react";
import React, { createContext, useContext } from "react";
export function createGlobalHook<ReturnValues>(useHook: () => ReturnValues): {
Provider: FunctionComponent<PropsWithChildren>;

@ -1,6 +1,7 @@
import { createDataset, DatasetChanges } from "o-dataset-pack";
import { GraphType } from "jsonld-dataset-proxy";
import { Quad } from "@rdfjs/types";
import type { DatasetChanges } from "o-dataset-pack";
import { createDataset } from "o-dataset-pack";
import type { GraphType } from "jsonld-dataset-proxy";
import type { Quad } from "@rdfjs/types";
import { defaultGraph, namedNode, quad as createQuad } from "@rdfjs/data-model";
export function graphNodeToString(graphNode: GraphType): string {
@ -14,7 +15,7 @@ export function stringToGraphNode(input: string): GraphType {
}
export function splitChangesByGraph(
changes: DatasetChanges<Quad>
changes: DatasetChanges<Quad>,
): Map<GraphType, DatasetChanges<Quad>> {
const changesMap: Record<string, DatasetChanges<Quad>> = {};
changes.added?.forEach((quad) => {
@ -26,7 +27,7 @@ export function splitChangesByGraph(
changesMap[graphHash].added = createDataset();
}
changesMap[graphHash].added?.add(
createQuad(quad.subject, quad.predicate, quad.object, quad.graph)
createQuad(quad.subject, quad.predicate, quad.object, quad.graph),
);
});
@ -39,7 +40,7 @@ export function splitChangesByGraph(
changesMap[graphHash].removed = createDataset();
}
changesMap[graphHash].removed?.add(
createQuad(quad.subject, quad.predicate, quad.object, quad.graph)
createQuad(quad.subject, quad.predicate, quad.object, quad.graph),
);
});

Loading…
Cancel
Save