Skip to content

Commit

Permalink
feat: TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
tpluscode committed Feb 20, 2024
1 parent 5216aa8 commit ea85198
Show file tree
Hide file tree
Showing 32 changed files with 2,769 additions and 2,228 deletions.
5 changes: 5 additions & 0 deletions .changeset/moody-eyes-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hydra-box": minor
---

Source changes to TypeScript
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
root = true

[*]
indent_size = 2
indent_style = space
insert_final_newline = true
4 changes: 2 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"extends": [ "@tpluscode/eslint-config/js" ],
"extends": [ "@tpluscode" ],
"env": {
"mocha": true
},
"overrides": [
{
"files": ["examples/**/*.js"],
"files": ["examples/**/*.ts"],
"rules": {
"no-console": "off",
"import/no-extraneous-dependencies": "off"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.nyc_output
coverage
node_modules
*.d.ts
138 changes: 69 additions & 69 deletions Api.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,75 @@
import rdf from '@zazuko/env-node'
import EcmaScriptLoader from 'rdf-loader-code/ecmaScript.js'
import LoaderRegistry from 'rdf-loaders-registry'
import EcmaScriptModuleLoader from 'rdf-loader-code/ecmaScriptModule.js'
import EcmaScriptLiteralLoader from 'rdf-loader-code/ecmaScriptLiteral.js'
import { replaceDatasetIRI } from './lib/replaceIRI.js'

/* eslint-disable camelcase */
import rdf from '@zazuko/env-node';

Check failure on line 2 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon

Check failure on line 2 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon
import EcmaScriptLoader from 'rdf-loader-code/ecmaScript.js';

Check failure on line 3 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon

Check failure on line 3 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon
import LoaderRegistryImpl from 'rdf-loaders-registry';

Check failure on line 4 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon

Check failure on line 4 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon
import EcmaScriptModuleLoader from 'rdf-loader-code/ecmaScriptModule.js';

Check failure on line 5 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon

Check failure on line 5 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon
import EcmaScriptLiteralLoader from 'rdf-loader-code/ecmaScriptLiteral.js';

Check failure on line 6 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon

Check failure on line 6 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon
import { replaceDatasetIRI } from './lib/replaceIRI.js';

Check failure on line 7 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon

Check failure on line 7 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon
class Api {
constructor({ term, dataset, graph, path, codePath } = {}) {
this.term = term
this.dataset = dataset
this.graph = graph
this.path = path
this.codePath = codePath
this.loaderRegistry = new LoaderRegistry()
this.tasks = []
this.initialized = false

EcmaScriptLoader.register(this.loaderRegistry)
EcmaScriptModuleLoader.register(this.loaderRegistry)
EcmaScriptLiteralLoader.register(this.loaderRegistry)
}

async init() {
if (!this._initialization) {
this._initialization = this._beginInit()
initialized;

Check failure on line 9 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 2 spaces but found 4

Check failure on line 9 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon

Check failure on line 9 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 2 spaces but found 4

Check failure on line 9 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon
path;

Check failure on line 10 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 2 spaces but found 4

Check failure on line 10 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon

Check failure on line 10 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 2 spaces but found 4

Check failure on line 10 in Api.js

View workflow job for this annotation

GitHub Actions / lint

Extra semicolon
codePath;
graph;
dataset;
_term;
loaderRegistry;
_initialization;
tasks;
constructor({ term, dataset, graph, path = '/api', codePath = process.cwd() } = {}) {
this._term = term;
this.dataset = dataset || rdf.dataset();
this.graph = graph;
this.path = path;
this.codePath = codePath;
this.loaderRegistry = new LoaderRegistryImpl();
this.tasks = [];
this.initialized = false;
EcmaScriptLoader.register(this.loaderRegistry);
EcmaScriptModuleLoader.register(this.loaderRegistry);
EcmaScriptLiteralLoader.register(this.loaderRegistry);
}

return this._initialization
}

fromFile(filePath) {
this.tasks.push(async () => {
this.dataset.addAll(await rdf.dataset().import(rdf.fromFile(filePath)))
})

return this
}

rebase(fromBaseIRI, toBaseIRI) {
this.tasks.push(async () => {
this.dataset = replaceDatasetIRI(fromBaseIRI, toBaseIRI, this.dataset)
})

return this
}

static fromFile(filePath, options) {
const api = new Api(options)

return api.fromFile(filePath)
}

async _beginInit() {
if (!this.dataset) {
this.dataset = rdf.dataset()
get term() {
return this._term;
}

for (const task of this.tasks) {
await task()
set term(term) {
this._term = term;
}

const apiDoc = rdf.clownface({ dataset: this.dataset, term: this.term, graph: this.graph })

if (apiDoc.has(rdf.ns.rdf.type, rdf.ns.hydra.ApiDocumentation).terms.length === 0) {
apiDoc.addOut(rdf.ns.rdf.type, rdf.ns.hydra.ApiDocumentation)

apiDoc.node().has(rdf.ns.rdf.type, rdf.ns.hydra.Class).forEach(supportedClass => {
apiDoc.addOut(rdf.ns.hydra.supportedClass, supportedClass)
})
async init() {
if (!this._initialization) {
this._initialization = this._beginInit();
}
return this._initialization;
}
fromFile(filePath) {
this.tasks.push(async () => {
rdf.dataset().addAll.call(this.dataset, await rdf.dataset().import(rdf.fromFile(filePath)));
});
return this;
}
rebase(fromBaseIRI, toBaseIRI) {
this.tasks.push(async () => {
this.dataset = replaceDatasetIRI(fromBaseIRI, toBaseIRI, this.dataset);
});
return this;
}
static fromFile(filePath, options) {
const api = new Api(options);
return api.fromFile(filePath);
}
async _beginInit() {
if (!this.dataset) {
this.dataset = rdf.dataset();
}
for (const task of this.tasks) {
await task();
}
const apiDoc = rdf.clownface({ dataset: this.dataset, term: this.term, graph: this.graph });
if (apiDoc.has(rdf.ns.rdf.type, rdf.ns.hydra.ApiDocumentation).terms.length === 0) {
apiDoc.addOut(rdf.ns.rdf.type, rdf.ns.hydra.ApiDocumentation);
apiDoc.any().has(rdf.ns.rdf.type, rdf.ns.hydra.Class).forEach(supportedClass => {
apiDoc.addOut(rdf.ns.hydra.supportedClass, supportedClass);
});
}
}
}
}

export default Api
export default Api;
103 changes: 103 additions & 0 deletions Api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/* eslint-disable camelcase */
import rdf from '@zazuko/env-node'
import EcmaScriptLoader from 'rdf-loader-code/ecmaScript.js'
import LoaderRegistryImpl, { LoaderRegistry } from 'rdf-loaders-registry'
import EcmaScriptModuleLoader from 'rdf-loader-code/ecmaScriptModule.js'
import EcmaScriptLiteralLoader from 'rdf-loader-code/ecmaScriptLiteral.js'
import type { NamedNode, DatasetCore, Quad_Graph } from '@rdfjs/types'
import { replaceDatasetIRI } from './lib/replaceIRI.js'

interface ApiInit<D extends DatasetCore = DatasetCore> {
term?: NamedNode
dataset?: D
graph?: NamedNode
path?: string
codePath?: string
}

class Api {
initialized: boolean
path: string
codePath: string
graph?: Quad_Graph | undefined
dataset: DatasetCore
private _term: NamedNode | undefined
loaderRegistry: LoaderRegistry
private _initialization?: Promise<void>
readonly tasks: Array<() => Promise<void>>

constructor({ term, dataset, graph, path = '/api', codePath = process.cwd() }: ApiInit = { }) {
this._term = term
this.dataset = dataset || rdf.dataset()
this.graph = graph
this.path = path
this.codePath = codePath
this.loaderRegistry = new LoaderRegistryImpl()
this.tasks = []
this.initialized = false

EcmaScriptLoader.register(this.loaderRegistry)
EcmaScriptModuleLoader.register(this.loaderRegistry)
EcmaScriptLiteralLoader.register(this.loaderRegistry)
}

get term() {
return this._term!
}

set term(term: NamedNode) {
this._term = term
}

async init() {
if (!this._initialization) {
this._initialization = this._beginInit()
}

return this._initialization
}

fromFile(filePath: string) {
this.tasks.push(async () => {
rdf.dataset().addAll.call(this.dataset, await rdf.dataset().import(rdf.fromFile(filePath)))
})

return this
}

rebase(fromBaseIRI: string | NamedNode, toBaseIRI: string | NamedNode) {
this.tasks.push(async () => {
this.dataset = replaceDatasetIRI(fromBaseIRI, toBaseIRI, this.dataset)
})

return this
}

static fromFile(filePath: string, options?: ApiInit) {
const api = new Api(options)

return api.fromFile(filePath)
}

async _beginInit() {
if (!this.dataset) {
this.dataset = rdf.dataset()
}

for (const task of this.tasks) {
await task()
}

const apiDoc = rdf.clownface({ dataset: this.dataset, term: this.term, graph: this.graph })

if (apiDoc.has(rdf.ns.rdf.type, rdf.ns.hydra.ApiDocumentation).terms.length === 0) {
apiDoc.addOut(rdf.ns.rdf.type, rdf.ns.hydra.ApiDocumentation)

apiDoc.any().has(rdf.ns.rdf.type, rdf.ns.hydra.Class).forEach(supportedClass => {
apiDoc.addOut(rdf.ns.hydra.supportedClass, supportedClass)
})
}
}
}

export default Api
91 changes: 46 additions & 45 deletions StoreResourceLoader.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@
import rdf from '@zazuko/env-node'

import rdf from '@zazuko/env-node';
import { isNamedNode } from 'is-graph-pointer';
export default class StoreResourceLoader {
constructor({ store }) {
this.store = store
}

async load(term) {
const dataset = await rdf.dataset().import(this.store.match(null, null, null, term))

if (dataset.size === 0) {
return null
store;
constructor({ store }) {
this.store = store;
}

const types = rdf.termSet(rdf.clownface({ dataset, term }).out(rdf.ns.rdf.type).terms)

return {
term,
prefetchDataset: dataset,
async dataset() {
return dataset
},
quadStream() {
return dataset.toStream()
},
types,
async load(term) {
const dataset = await rdf.dataset().import(this.store.match(null, null, null, term));
if (dataset.size === 0) {
return null;
}
const types = rdf.clownface({ dataset, term })
.out(rdf.ns.rdf.type)
.filter(isNamedNode);
return {
term,
prefetchDataset: dataset,
async dataset() {
return dataset;
},
quadStream() {
return dataset.toStream();
},
types: rdf.termSet(types.terms),
};
}
}

async forClassOperation(term) {
const resource = await this.load(term)

return resource ? [resource] : []
}

async forPropertyOperation(term) {
const dataset = await rdf.dataset().import(this.store.match(null, null, term, null))
const result = []

for (const quad of dataset) {
result.push({
property: quad.predicate,
object: quad.object,
...await this.load(quad.subject),
})
async forClassOperation(term) {
const resource = await this.load(term);
return resource ? [resource] : [];
}
async forPropertyOperation(term) {
const dataset = await rdf.dataset().import(this.store.match(null, null, term, null));
const result = [];
for (const quad of dataset) {
if (quad.subject.termType !== 'NamedNode')
continue;
if (quad.object.termType !== 'NamedNode')
continue;
const loaded = await this.load(quad.subject);
if (!loaded)
continue;
result.push({
property: quad.predicate,
object: quad.object,
...loaded,
});
}
return result;
}

return result
}
}
Loading

0 comments on commit ea85198

Please sign in to comment.