Skip to content

Commit

Permalink
update example to use ESM alcaeus
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Feb 15, 2024
1 parent 00af587 commit 2942d2b
Show file tree
Hide file tree
Showing 19 changed files with 838 additions and 2,342 deletions.
11 changes: 10 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,14 @@
"extends": [ "@tpluscode/eslint-config/js" ],
"env": {
"mocha": true
}
},
"overrides": [
{
"files": ["examples/**/*.js"],
"rules": {
"no-console": "off",
"ne-extraneous-dependencies": "off"
}
}
]
}
10 changes: 5 additions & 5 deletions examples/blog/api.ttl
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
hydra:expects <TimeRange>;
hydra:method "GET";
hydra:returns <Result>;
code:implementedBy [ a code:EcmaScript;
code:implementedBy [ a code:EcmaScriptModule;
code:link <file:./blog.js#get>
].

<blog#post> a hydra:SupportedOperation;
hydra:expects <Post>;
hydra:method "POST";
code:implementedBy [ a code:EcmaScript;
code:implementedBy [ a code:EcmaScriptModule;
code:link <file:./blog.js#post>
].

Expand Down Expand Up @@ -54,7 +54,7 @@
<post#get> a hydra:SupportedOperation;
hydra:method "GET";
hydra:returns <Post>;
code:implementedBy [ a code:EcmaScript;
code:implementedBy [ a code:EcmaScriptModule;
code:link <file:./post.js#get>
].

Expand All @@ -63,7 +63,7 @@
hydra:title "Post comment" ;
hydra:expects <Comment>;
hydra:returns <Post>;
code:implementedBy [ a code:EcmaScript;
code:implementedBy [ a code:EcmaScriptModule;
code:link <file:./comment.js#post>
].

Expand Down Expand Up @@ -96,7 +96,7 @@
<category#get> a hydra:SupportedOperation;
hydra:method "GET";
hydra:returns <Category>;
code:implementedBy [ a code:EcmaScript;
code:implementedBy [ a code:EcmaScriptModule;
code:link <file:./category.js#get>
].

Expand Down
37 changes: 15 additions & 22 deletions examples/blog/blog.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
const rdf = { ...require('@rdfjs/data-model'), ...require('@rdfjs/dataset') }
const vocab = require('@tpluscode/rdf-ns-builders')
const generateIri = require('./lib/generateIri')
const ns = require('./lib/namespaces')
const rebase = require('./lib/rebase')
const validate = require('./lib/validate')
import rdf from '@zazuko/env-node'
import generateIri from './lib/generateIri.js'
import rebase from './lib/rebase.js'
import validate from './lib/validate.js'

async function get (req, res) {
export async function get(req, res) {
const url = rdf.namedNode(req.absoluteUrl())

const dataset = await req.hydra.resource.dataset()
if (req.dataset) {
const filters = await req.dataset()

const fromQuad = [...filters.match(null, ns.schema.from, null, null)][0]
const fromQuad = [...filters.match(null, rdf.ns.schema.from, null, null)][0]
const from = fromQuad && fromQuad.object

const toQuad = [...filters.match(null, ns.schema.to, null, null)][0]
const toQuad = [...filters.match(null, rdf.ns.schema.to, null, null)][0]
const to = toQuad && toQuad.object

if (from || to) {
console.log(`date filter: ${from && from.value} - ${to && to.value}`)
}

const tagQuads = [...filters.match(null, ns.schema.tag, null, null)]
const tagQuads = [...filters.match(null, rdf.ns.schema.tag, null, null)]
const tags = tagQuads.map(tagQuad => tagQuad.object.value)

if (tags) {
Expand All @@ -31,38 +29,33 @@ async function get (req, res) {

dataset.add(rdf.quad(
req.hydra.term,
vocab.hydra.view,
url
rdf.ns.hydra.view,
url,
))
}

res.dataset(dataset)
}

async function post (req, res, next) {
export async function post(req, res, next) {
try {
const rawContent = await req.dataset()

await validate(rawContent)

const blogTerm = req.hydra.resource.term
const postTerm = await generateIri(ns.schema.Post, blogTerm)
const postTerm = await generateIri(rdf.ns.schema.Post, blogTerm)
const commentsTerm = rdf.namedNode(`${postTerm.value}/comments`)
const content = rebase(rawContent, postTerm)

content.add(rdf.quad(postTerm, vocab.dc11.date, rdf.literal((new Date()).toISOString(), vocab.xsd.date)))
content.add(rdf.quad(postTerm, ns.schema.comments, commentsTerm))
content.add(rdf.quad(postTerm, rdf.ns.dc11.date, rdf.literal((new Date()).toISOString(), rdf.ns.xsd.date)))
content.add(rdf.quad(postTerm, rdf.ns.schema.comments, commentsTerm))

await req.app.locals.store.write(postTerm, content)
await req.app.locals.store.write(blogTerm, rdf.dataset([rdf.quad(blogTerm, ns.schema.post, postTerm)]))
await req.app.locals.store.write(blogTerm, rdf.dataset([rdf.quad(blogTerm, rdf.ns.schema.post, postTerm)]))

res.status(201).set('location', postTerm.value).end()
} catch (err) {
next(err)
}
}

module.exports = {
get,
post
}
6 changes: 1 addition & 5 deletions examples/blog/category.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
async function get (req, res) {
export async function get(req, res) {
res.dataset(await req.hydra.resource.dataset())
}

module.exports = {
get
}
4 changes: 4 additions & 0 deletions examples/blog/client/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import parent, { Environment } from '@zazuko/env-node'
import alcaeus from 'alcaeus'

Check failure on line 2 in examples/blog/client/env.js

View workflow job for this annotation

GitHub Actions / lint

'alcaeus' should be listed in the project's dependencies, not devDependencies

export default new Environment([...alcaeus()], { parent })
9 changes: 4 additions & 5 deletions examples/blog/client/get-blog-alcaeus.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
const Hydra = require('alcaeus/with-parsers')
const { rdfs } = require('@tpluscode/rdf-ns-builders')
import rdf from './env.js'

const baseUrl = 'http://localhost:9000/'

async function getBlog () {
const blog = await Hydra.loadResource(baseUrl)
async function getBlog() {
const blog = await rdf.hydra.loadResource(baseUrl)
return blog.representation.root
}

getBlog()
.then(res => console.log(`Blog title: ${res[rdfs.label.value].value}`))
.then(res => console.log(`Blog title: ${res[rdf.ns.rdfs.label.value].value}`))
10 changes: 5 additions & 5 deletions examples/blog/client/post-comment-alcaeus.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
const Hydra = require('alcaeus/with-parsers')
import rdf from './env.js'

const baseUrl = 'http://localhost:9000/'

async function postComment () {
const resources = await Hydra.loadResource(`${baseUrl}post/1`)
async function postComment() {
const resources = await rdf.hydra.loadResource(`${baseUrl}post/1`)
const post = resources.representation.root
const comments = post['http://localhost:9000/api/schema/comments']
const createComment = comments.findOperations({ byMethod: 'POST' })[0]

const invocation = await createComment.invoke(JSON.stringify({
'@id': '',
'@type': 'http://localhost:9000/api/schema/Comment',
'http://www.w3.org/2000/01/rdf-schema#label': 'new comment created by alcaeus'
'http://www.w3.org/2000/01/rdf-schema#label': 'new comment created by alcaeus',
}), {
'Content-Type': 'application/ld+json'
'Content-Type': 'application/ld+json',
})

console.log(`comment created: ${invocation.response.xhr.ok}`)
Expand Down
10 changes: 5 additions & 5 deletions examples/blog/client/post-post-alcaeus.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
const Hydra = require('alcaeus/with-parsers')
import rdf from './env.js'

const baseUrl = 'http://localhost:9000/'

async function postPost () {
const post = await Hydra.loadResource(baseUrl)
async function postPost() {
const post = await rdf.hydra.loadResource(baseUrl)
const blog = post.representation.root
const createPost = blog.findOperations({ byMethod: 'POST' })[0]

const invocation = await createPost.invoke(JSON.stringify({
'@id': '',
'@type': 'http://localhost:9000/api/schema/Post',
'http://www.w3.org/2000/01/rdf-schema#label': 'new post created by alcaeus'
'http://www.w3.org/2000/01/rdf-schema#label': 'new post created by alcaeus',
}), {
'Content-Type': 'application/ld+json'
'Content-Type': 'application/ld+json',
})

console.log(`post created: ${invocation.response.xhr.ok}`)
Expand Down
18 changes: 6 additions & 12 deletions examples/blog/comment.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
const rdf = { ...require('@rdfjs/data-model'), ...require('@rdfjs/dataset') }
const { dc11, xsd } = require('@tpluscode/rdf-ns-builders')
const ns = require('./lib/namespaces')
const rebase = require('./lib/rebase')
const validate = require('./lib/validate')
import rdf from '@zazuko/env-node'
import rebase from './lib/rebase.js'
import validate from './lib/validate.js'

async function post (req, res, next) {
export async function post(req, res, next) {
try {
const rawContent = await req.dataset()

Expand All @@ -15,8 +13,8 @@ async function post (req, res, next) {
const commentTerm = rdf.blankNode()
const content = rebase(rawContent, commentTerm)

content.add(rdf.quad(commentTerm, dc11.date, rdf.literal((new Date()).toISOString(), xsd.date)))
content.add(rdf.quad(commentsTerm, ns.schema.comment, commentTerm))
content.add(rdf.quad(commentTerm, rdf.ns.dc11.date, rdf.literal((new Date()).toISOString(), rdf.ns.xsd.date)))
content.add(rdf.quad(commentsTerm, rdf.ns.schema.comment, commentTerm))

await req.app.locals.store.write(postTerm, content)

Expand All @@ -25,7 +23,3 @@ async function post (req, res, next) {
next(err)
}
}

module.exports = {
post
}
19 changes: 8 additions & 11 deletions examples/blog/lib/ResourceStore.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
const { fromStream, toStream } = require('rdf-dataset-ext')
const rdf = { ...require('@rdfjs/data-model'), ...require('@rdfjs/dataset') }
import rdf from '@zazuko/env-node'

class ResourceStore {
constructor ({ factory = rdf, quadStore }) {
export default class ResourceStore {
constructor({ factory = rdf, quadStore }) {
this.factory = factory
this.quadStore = quadStore
}

async read (resource) {
const dataset = await fromStream(this.factory.dataset(), this.quadStore.match(null, null, null, resource))
async read(resource) {
const dataset = await this.factory.dataset().import(this.quadStore.match(null, null, null, resource))

return this.factory.dataset([...dataset].map(quad => this.factory.quad(quad.subject, quad.predicate, quad.object)))
}

async write (resource, dataset) {
const stream = toStream(this.factory.dataset([...dataset].map(quad => {
async write(resource, dataset) {
const stream = this.factory.dataset([...dataset].map(quad => {
return this.factory.quad(quad.subject, quad.predicate, quad.object, resource)
})))
})).toStream()

const events = this.quadStore.import(stream)

Expand All @@ -26,5 +25,3 @@ class ResourceStore {
})
}
}

module.exports = ResourceStore
10 changes: 4 additions & 6 deletions examples/blog/lib/generateIri.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
const rdf = require('@rdfjs/data-model')
const ns = require('./namespaces')
import rdf from '@zazuko/env-node'

// Generates IRIs for new resources based on the given rdf:type and parent.
// An actual implementation could use a SPARQL query to find the next IRI.
// A cluster version could use a in memory key value store + SPARQL init.
async function generateIri (type, parent) {
if (type.equals(ns.schema.Post)) {

export default async function generateIri(type, parent) {
if (type.equals(rdf.ns.schema.Post)) {
const id = Math.floor(Math.random() * 100000)

return rdf.namedNode(`${parent.value}post/${id}`)
}

throw new Error(`unknown type: ${type.value}`)
}

module.exports = generateIri
15 changes: 5 additions & 10 deletions examples/blog/lib/iri.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
const { resolve: resolvePath } = require('path')
const { URL } = require('url')
import { URL } from 'node:url'
import { resolve as resolvePath } from 'node:path'

function isRelative (iri) {
return !iri.match(new RegExp('^[a-z]+:'))
export function isRelative(iri) {
return !iri.match(/^[a-z]+:/)
}

function resolve (baseIRI, relative) {
export function resolve(baseIRI, relative) {
const url = new URL(baseIRI)

url.pathname = resolvePath(url.pathname, relative)

return url.toString()
}

module.exports = {
isRelative,
resolve
}
5 changes: 0 additions & 5 deletions examples/blog/lib/namespaces.js

This file was deleted.

12 changes: 5 additions & 7 deletions examples/blog/lib/rebase.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const rdf = { ...require('@rdfjs/data-model'), ...require('@rdfjs/dataset') }
const { isRelative, resolve } = require('./iri')
import rdf from '@zazuko/env-node'
import { isRelative, resolve } from './iri.js'

function rebaseBlankNode (dataset, base) {
function rebaseBlankNode(dataset, base) {
const mappedTerms = new Map([['', base]])

return rdf.dataset([...dataset].map(quad => {
Expand All @@ -19,7 +19,7 @@ function rebaseBlankNode (dataset, base) {
}))
}

function rebaseNamedNode (dataset, base) {
function rebaseNamedNode(dataset, base) {
return rdf.dataset([...dataset].map(quad => {
if (isRelative(quad.subject.value)) {
return rdf.quad(rdf.namedNode(resolve(base.value, quad.subject.value)), quad.predicate, quad.object, quad.graph)
Expand All @@ -29,7 +29,7 @@ function rebaseNamedNode (dataset, base) {
}))
}

function rebase (dataset, base) {
export default function rebase(dataset, base) {
if (base.termType === 'BlankNode') {
return rebaseBlankNode(dataset, base)
}
Expand All @@ -40,5 +40,3 @@ function rebase (dataset, base) {

throw new Error(`${base.termType} not supported for rebasing`)
}

module.exports = rebase
Loading

0 comments on commit 2942d2b

Please sign in to comment.