@tranbau
This is how i typically use it:
import { fetch } from '@inrupt/solid-client-authn-browser'
import {
parseRdf,
toSparqlUpdate,
toTurtle,
startTransaction,
commitTransaction
} from 'ldo'
import { foaf, rdf } from 'rdf-namespaces'
import { FoafProfileShapeType } from './ldo/foafProfile.shapeTypes'
// FoafProfileShapeType needs to be generated by ldo-cli first, based on the shape you provide
const example = async () => {
// fetch (turtle) document from uri
const uri = 'https://example.com/profile/extended' // uri of document (hashes are ok)
const uriOfThing = 'https://example.com/profile/card#me' // uri of thing we want to read
// often these two uris are the same
// or you might not need uriOfThing, if you find it by matching predicate and/or object...
// fetch the (turtle) document first
const response = await fetch(uri)
const doc = await response.text()
// use ldo to parse it
const ldoDataset = await parseRdf(doc, { baseIRI: uri })
const profile = ldoDataset
.usingType(FoafProfileShapeType)
.fromSubject(uriOfThing)
// uri of subject, in this case it would probably be person's webId
// OR you can find the thing by matching its predicate and object
// matcher returns array of matched things
const alsoProfiles = ldoDataset
.usingType(FoafProfileShapeType)
.matchSubject(rdf.type, foaf.PersonalProfileDocument)
// there is also matchObject method
// now you can use the profile like normal TypeScript/JavaScript object
const name = profile.name
const friends = profile.knows?.map(friend => friend['@id'])
}
You can also create or modify the object with PATCH
const ldoDataset = await parseRdf(doc, { baseIRI: uri })
// or for new thing
const ldoDataset = createLdoDataset()
const profile = ldoDataset
.usingType(FoafProfileShapeType)
.fromSubject(uriOfThing)
startTransaction(profile)
profile.name = 'New Name'
const patch = await toSparqlUpdate(profile)
// and you can send the patch to the server now
await fetch(uri, {
method: 'PATCH',
body: patch,
headers: { 'content-type': 'application/sparql-update' }
BUT! Please keep in mind that PATCH application/sparql-update
is not specified in Solid Protocol, so it may not be supported. So instead we can do PATCH with text/n3
// you need to do this BEFORE committing transaction
const n3patch = await toN3Patch(profile)
// and you can send the patch to the server now
await fetch(uri, {
method: 'PATCH',
body: n3patch,
headers: { 'content-type': 'text/n3' }
})
// where i defined toN3Patch myself, based on
// https://solidproject.org/TR/protocol#n3-patch
// but i hope it will be included in the library:
import { Dataset } from '@rdfjs/types'
import { transactionChanges } from 'ldo'
import { datasetToString } from 'ldo/dist/datasetConverters'
import { LdoBase } from 'ldo/dist/util'
export async function toN3Patch(ldo: LdoBase): Promise<string> {
const changes = transactionChanges(ldo)
const patch = `
_:patch a <${solid.InsertDeletePatch}>;
<${solid.inserts}> { ${
changes.added
? await datasetToString(changes.added as Dataset, { format: 'N3' })
: ''
} };
<${solid.deletes}> { ${
changes.removed
? await datasetToString(changes.removed as Dataset, { format: 'N3' })
: ''
} }.`
return patch
}
Or, if you want to use POST or PUT instead,
// first, commit the transaction
commitTransaction(profile)
const doc = await toTurtle(profile)
// and send it to server with PUT or POST
You’ll find more examples in LDO repository README.
i’m not affiliated with this library. i just like to use it.
the above code hasn’t been run, mistakes have been included