From c055d611ab5728c97147ca3e5dd3e0fcc4ca3b69 Mon Sep 17 00:00:00 2001 From: Tomasz Pluskiewicz Date: Wed, 11 Oct 2023 14:35:12 +0200 Subject: [PATCH] feat: loader package --- .changeset/brave-tips-speak.md | 5 ++ .changeset/empty-lions-roll.md | 5 ++ package-lock.json | 16 +++- packages/loader/index.ts | 90 +++++++++++++++++++ .../lib/loadDataset.ts | 2 +- packages/loader/package.json | 16 ++++ packages/vocabularies/bin/vocab.js | 2 +- packages/vocabularies/expandWithCheck.ts | 3 +- packages/vocabularies/package.json | 2 +- packages/vocabularies/vocabularies.ts | 86 +----------------- 10 files changed, 139 insertions(+), 88 deletions(-) create mode 100644 .changeset/brave-tips-speak.md create mode 100644 .changeset/empty-lions-roll.md create mode 100644 packages/loader/index.ts rename packages/{vocabularies => loader}/lib/loadDataset.ts (86%) create mode 100644 packages/loader/package.json diff --git a/.changeset/brave-tips-speak.md b/.changeset/brave-tips-speak.md new file mode 100644 index 00000000..c2643abb --- /dev/null +++ b/.changeset/brave-tips-speak.md @@ -0,0 +1,5 @@ +--- +"@zazuko/vocabulary-loader": major +--- + +First release diff --git a/.changeset/empty-lions-roll.md b/.changeset/empty-lions-roll.md new file mode 100644 index 00000000..7b0f9f8a --- /dev/null +++ b/.changeset/empty-lions-roll.md @@ -0,0 +1,5 @@ +--- +"@zazuko/prefixes": patch +--- + +Export required type diff --git a/package-lock.json b/package-lock.json index 21cdf985..d6618246 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1978,6 +1978,10 @@ "resolved": "packages/vocabularies", "link": true }, + "node_modules/@zazuko/vocabulary-loader": { + "resolved": "packages/loader", + "link": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -10753,6 +10757,15 @@ "@types/rdfjs__serializer-rdfjs": "^0.0.2" } }, + "packages/loader": { + "version": "0.0.0", + "dependencies": { + "@rdfjs/parser-n3": "^2.0.1", + "@types/rdfjs__environment": "^0.1", + "@zazuko/env": "^1.6.1", + "rdf-dataset-ext": "^1.1.0" + } + }, "packages/prefixes": { "name": "@zazuko/prefixes", "version": "2.0.0", @@ -10763,8 +10776,6 @@ "version": "2.0.1", "license": "MIT", "dependencies": { - "@rdfjs/parser-n3": "^2.0.1", - "@types/rdfjs__environment": "^0.1", "@vocabulary/acl": "^1.0.0", "@vocabulary/as": "^1.0.0", "@vocabulary/bibo": "^1.0.0", @@ -10869,6 +10880,7 @@ "@vocabulary/xsd": "^1.0.0", "@zazuko/env": "^1.3.0", "@zazuko/prefixes": "^2.0.0", + "@zazuko/vocabulary-loader": "^0.0.0", "commander": "^10.0.0", "rdf-dataset-ext": "^1", "readable-stream": "^4.3.0" diff --git a/packages/loader/index.ts b/packages/loader/index.ts new file mode 100644 index 00000000..474eee9d --- /dev/null +++ b/packages/loader/index.ts @@ -0,0 +1,90 @@ +/* eslint-disable no-console */ +import { Stream, DataFactory, DatasetCore, DatasetCoreFactory } from 'rdf-js' +import { Readable } from 'stream' +import rdf from '@zazuko/env' +import type { Environment } from '@rdfjs/environment/Environment.js' +import ParserN3 from '@rdfjs/parser-n3' +import fromStream from 'rdf-dataset-ext/fromStream.js' +import addAll from 'rdf-dataset-ext/addAll.js' +import toStream from 'rdf-dataset-ext/toStream.js' +import { loadDatasetStream } from './lib/loadDataset.js' + +export type Datasets

> = Record + +export interface VocabulariesOptions

> { + only?: (keyof P)[] | null + factory?: Environment +} + +export interface VocabulariesDatasetOptions

> extends VocabulariesOptions

{ + stream?: false +} + +export interface VocabulariesStreamOptions

> extends VocabulariesOptions

{ + stream: true +} + +export interface Loader

> { + (options?: VocabulariesDatasetOptions

): Promise> + (options: VocabulariesStreamOptions

): Promise +} + +export function create

>(prefixMap: P): Loader

{ + return async function vocabularies({ only = null, factory = rdf, stream = false }: VocabulariesDatasetOptions

| VocabulariesStreamOptions

= {}) { + let selectedPrefixes: (keyof typeof prefixMap)[] = [] + + if (!!only && Array.isArray(only)) { + only.forEach((prefix: keyof P) => { + if (prefix in prefixMap) { + selectedPrefixes.push(prefix) + } else { + console.warn(`unknown prefix '${String(prefix)}'`) + } + }) + } + if (!selectedPrefixes.length) { + selectedPrefixes = Object.keys(prefixMap) + } + + const promises = selectedPrefixes.map((prefix) => loadFile(prefix, { customSelection: !!only, factory })) + const datasets = await Promise.all(promises) + + if (stream !== false) { + let combinedDataset = factory.dataset() + datasets.forEach((dataset) => { + if (dataset && dataset.size) { + combinedDataset = addAll(combinedDataset, dataset) + } + }) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return toStream(combinedDataset) as any + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const result: Datasets

= {} as any + datasets.forEach((dataset, i) => { + if (dataset && dataset.size) { + result[selectedPrefixes[i]] = dataset + } + }) + return result + } +} + +interface LoadFileOptions { + customSelection?: boolean + factory: Environment +} + +export async function loadFile

>(prefix: keyof P, { customSelection, factory }: LoadFileOptions) { + try { + const parserN3 = new ParserN3() + const readStream = await loadDatasetStream(String(prefix)) + const quadStream = parserN3.import(readStream) + return fromStream(factory.dataset(), quadStream) + } catch { + if (customSelection) { + console.warn(`unavailable prefix '${String(prefix)}'`) + } + } +} diff --git a/packages/vocabularies/lib/loadDataset.ts b/packages/loader/lib/loadDataset.ts similarity index 86% rename from packages/vocabularies/lib/loadDataset.ts rename to packages/loader/lib/loadDataset.ts index 466ba5e1..83379169 100644 --- a/packages/vocabularies/lib/loadDataset.ts +++ b/packages/loader/lib/loadDataset.ts @@ -1,6 +1,6 @@ import fs from 'fs' import module from 'module' -import type prefixes from '../prefixes.js' +import type prefixes from '@zazuko/prefixes' const { resolve } = module.createRequire(import.meta.url) diff --git a/packages/loader/package.json b/packages/loader/package.json new file mode 100644 index 00000000..d54e7f7b --- /dev/null +++ b/packages/loader/package.json @@ -0,0 +1,16 @@ +{ + "name": "@zazuko/vocabulary-loader", + "version": "0.0.0", + "type": "module", + "main": "index.js", + "files": [ + "**/*.js", + "**/*.d.ts" + ], + "dependencies": { + "@zazuko/env": "^1.6.1", + "@rdfjs/parser-n3": "^2.0.1", + "@types/rdfjs__environment": "^0.1", + "rdf-dataset-ext": "^1.1.0" + } +} diff --git a/packages/vocabularies/bin/vocab.js b/packages/vocabularies/bin/vocab.js index 89ebd2e1..861bf7c6 100755 --- a/packages/vocabularies/bin/vocab.js +++ b/packages/vocabularies/bin/vocab.js @@ -3,7 +3,7 @@ import { promisify } from 'util' import { program } from 'commander' import stream from 'readable-stream' -import { loadDatasetStream } from '../lib/loadDataset.js' +import { loadDatasetStream } from '@zazuko/vocabulary-loader/lib/loadDataset.js' import prefixes from '../prefixes.js' const finished = promisify(stream.finished) diff --git a/packages/vocabularies/expandWithCheck.ts b/packages/vocabularies/expandWithCheck.ts index 01d78414..bada0524 100644 --- a/packages/vocabularies/expandWithCheck.ts +++ b/packages/vocabularies/expandWithCheck.ts @@ -4,7 +4,8 @@ import { expand, getParts } from './expand.js' import { vocabularies, Datasets } from './vocabularies.js' // memoizing the prefixes already used in 'expand' -export const loadedPrefixes: Datasets = {} +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const loadedPrefixes: Datasets = {} type Types = (string | NamedNode)[] diff --git a/packages/vocabularies/package.json b/packages/vocabularies/package.json index 10a1dfba..b8566060 100644 --- a/packages/vocabularies/package.json +++ b/packages/vocabularies/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@rdfjs/parser-n3": "^2.0.1", - "@types/rdfjs__environment": "^0.1", + "@zazuko/vocabulary-loader": "^0.0.0", "@vocabulary/acl": "^1.0.0", "@vocabulary/as": "^1.0.0", "@vocabulary/bibo": "^1.0.0", diff --git a/packages/vocabularies/vocabularies.ts b/packages/vocabularies/vocabularies.ts index cb834d87..7103acd7 100644 --- a/packages/vocabularies/vocabularies.ts +++ b/packages/vocabularies/vocabularies.ts @@ -1,84 +1,6 @@ -/* eslint-disable no-console */ -import { Stream, DataFactory, DatasetCore, DatasetCoreFactory } from 'rdf-js' -import { Readable } from 'stream' -import rdf from '@zazuko/env' -import type { Environment } from '@rdfjs/environment/Environment.js' -import prefixes from '@zazuko/prefixes' -import ParserN3 from '@rdfjs/parser-n3' -import fromStream from 'rdf-dataset-ext/fromStream.js' -import addAll from 'rdf-dataset-ext/addAll.js' -import toStream from 'rdf-dataset-ext/toStream.js' -import { loadDatasetStream } from './lib/loadDataset.js' +import { create } from '@zazuko/vocabulary-loader' +import prefixes from './prefixes.js' -export type Datasets = Record +export { loadFile, Datasets } from '@zazuko/vocabulary-loader' -interface VocabulariesOptions { - only?: (keyof typeof prefixes)[] | null - factory?: Environment -} - -interface VocabulariesDatasetOptions extends VocabulariesOptions { - stream?: false -} - -interface VocabulariesStreamOptions extends VocabulariesOptions { - stream: true -} - -export async function vocabularies (options?: VocabulariesDatasetOptions): Promise -export async function vocabularies (options: VocabulariesStreamOptions): Promise -export async function vocabularies({ only = null, factory = rdf, stream = false }: VocabulariesDatasetOptions | VocabulariesStreamOptions = {}) { - let selectedPrefixes: (keyof typeof prefixes)[] = [] - - if (!!only && Array.isArray(only)) { - only.forEach((prefix: keyof typeof prefixes) => { - if (prefix in prefixes) { - selectedPrefixes.push(prefix) - } else { - console.warn(`unknown prefix '${prefix}'`) - } - }) - } - if (!selectedPrefixes.length) { - selectedPrefixes = Object.keys(prefixes) - } - - const promises = selectedPrefixes.map((prefix) => loadFile(prefix, { customSelection: !!only, factory })) - const datasets = await Promise.all(promises) - - if (stream !== false) { - let combinedDataset = factory.dataset() - datasets.forEach((dataset) => { - if (dataset && dataset.size) { - combinedDataset = addAll(combinedDataset, dataset) - } - }) - return toStream(combinedDataset) as any - } - - const result: Datasets = {} - datasets.forEach((dataset, i) => { - if (dataset && dataset.size) { - result[selectedPrefixes[i]] = dataset - } - }) - return result -} - -interface LoadFileOptions { - customSelection?: boolean - factory: Environment -} - -export async function loadFile(prefix: keyof typeof prefixes, { customSelection, factory }: LoadFileOptions) { - try { - const parserN3 = new ParserN3() - const readStream = await loadDatasetStream(prefix) - const quadStream = parserN3.import(readStream) - return fromStream(factory.dataset(), quadStream) - } catch { - if (customSelection) { - console.warn(`unavailable prefix '${prefix}'`) - } - } -} +export const vocabularies = create(prefixes)