@dwk/rdf 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +125 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/jsonld.d.ts +44 -0
- package/dist/jsonld.d.ts.map +1 -0
- package/dist/jsonld.js +620 -0
- package/dist/jsonld.js.map +1 -0
- package/dist/media-types.d.ts +23 -0
- package/dist/media-types.d.ts.map +1 -0
- package/dist/media-types.js +33 -0
- package/dist/media-types.js.map +1 -0
- package/dist/store.d.ts +38 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +55 -0
- package/dist/store.js.map +1 -0
- package/dist/turtle.d.ts +30 -0
- package/dist/turtle.d.ts.map +1 -0
- package/dist/turtle.js +20 -0
- package/dist/turtle.js.map +1 -0
- package/package.json +48 -0
- package/src/index.ts +98 -0
- package/src/jsonld.ts +813 -0
- package/src/media-types.ts +36 -0
- package/src/store.ts +106 -0
- package/src/turtle.ts +55 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RDF media-type registry for content negotiation. Maps the RDF serializations
|
|
3
|
+
* `@dwk/solid-pod` negotiates over to the internal format identifier used by
|
|
4
|
+
* the Turtle ({@link ./turtle}) and JSON-LD ({@link ./jsonld}) code paths.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Serialization formats this package can parse and write. */
|
|
8
|
+
export type RdfFormat = "Turtle" | "TriG" | "N-Triples" | "N-Quads" | "JSON-LD";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Canonical media type → format. Keys are lowercase essence (no parameters).
|
|
12
|
+
*
|
|
13
|
+
* Note `application/json` is deliberately **not** an RDF type here: JSON-LD's
|
|
14
|
+
* media type is `application/ld+json`, and treating arbitrary `application/json`
|
|
15
|
+
* bodies as a graph would let non-RDF JSON be misparsed on write/PATCH. A
|
|
16
|
+
* read-only `application/json` → JSON-LD convenience can be opted into at the
|
|
17
|
+
* content-negotiation layer instead (see `@dwk/solid-pod` negotiation).
|
|
18
|
+
*/
|
|
19
|
+
export const MEDIA_TYPE_FORMATS: Readonly<Record<string, RdfFormat>> = {
|
|
20
|
+
"text/turtle": "Turtle",
|
|
21
|
+
"application/trig": "TriG",
|
|
22
|
+
"application/n-triples": "N-Triples",
|
|
23
|
+
"application/n-quads": "N-Quads",
|
|
24
|
+
"application/ld+json": "JSON-LD",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a media type (with optional parameters / charset, any casing) to its
|
|
29
|
+
* RDF format, or `undefined` when the media type is not an RDF serialization.
|
|
30
|
+
*/
|
|
31
|
+
export function formatForMediaType(mediaType: string): RdfFormat | undefined {
|
|
32
|
+
// Guard against a missing Content-Type header passed straight through.
|
|
33
|
+
if (typeof mediaType !== "string") return undefined;
|
|
34
|
+
const essence = mediaType.split(";")[0]?.trim().toLowerCase();
|
|
35
|
+
return essence ? MEDIA_TYPE_FORMATS[essence] : undefined;
|
|
36
|
+
}
|
package/src/store.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { DataFactory } from "n3";
|
|
2
|
+
import type { Quad, Quad_Graph, Quad_Object, Term } from "n3";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Triple ↔ store helpers.
|
|
6
|
+
*
|
|
7
|
+
* The quad store in `@dwk/store` (DO-SQLite) and `@dwk/solid-pod` content
|
|
8
|
+
* negotiation need a flat, JSON-serializable representation of RDF terms that
|
|
9
|
+
* maps cleanly onto SQLite columns and survives a structured-clone boundary.
|
|
10
|
+
* These helpers convert between N3.js / RDF-JS {@link Quad}s and that
|
|
11
|
+
* representation without pulling in any storage backend.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** RDF term kinds representable in the store. */
|
|
15
|
+
export type StoredTermType =
|
|
16
|
+
| "NamedNode"
|
|
17
|
+
| "BlankNode"
|
|
18
|
+
| "Literal"
|
|
19
|
+
| "DefaultGraph";
|
|
20
|
+
|
|
21
|
+
/** Flat, JSON-serializable representation of a single RDF term. */
|
|
22
|
+
export interface StoredTerm {
|
|
23
|
+
readonly termType: StoredTermType;
|
|
24
|
+
/** Lexical value: IRI, blank-node label, literal value, or `""` for the default graph. */
|
|
25
|
+
readonly value: string;
|
|
26
|
+
/** Literals only: the datatype IRI (omitted for `rdf:langString`). */
|
|
27
|
+
readonly datatype?: string;
|
|
28
|
+
/** Language-tagged literals only: the BCP-47 language tag. */
|
|
29
|
+
readonly language?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Flat, JSON-serializable representation of a single quad. */
|
|
33
|
+
export interface StoredQuad {
|
|
34
|
+
readonly subject: StoredTerm;
|
|
35
|
+
readonly predicate: StoredTerm;
|
|
36
|
+
readonly object: StoredTerm;
|
|
37
|
+
readonly graph: StoredTerm;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const XSD_STRING = "http://www.w3.org/2001/XMLSchema#string";
|
|
41
|
+
|
|
42
|
+
/** Convert an RDF term into its flat store representation. */
|
|
43
|
+
export function termToStored(term: Term): StoredTerm {
|
|
44
|
+
switch (term.termType) {
|
|
45
|
+
case "NamedNode":
|
|
46
|
+
return { termType: "NamedNode", value: term.value };
|
|
47
|
+
case "BlankNode":
|
|
48
|
+
return { termType: "BlankNode", value: term.value };
|
|
49
|
+
case "DefaultGraph":
|
|
50
|
+
return { termType: "DefaultGraph", value: "" };
|
|
51
|
+
case "Literal":
|
|
52
|
+
return term.language
|
|
53
|
+
? { termType: "Literal", value: term.value, language: term.language }
|
|
54
|
+
: {
|
|
55
|
+
termType: "Literal",
|
|
56
|
+
value: term.value,
|
|
57
|
+
datatype: term.datatype.value,
|
|
58
|
+
};
|
|
59
|
+
default:
|
|
60
|
+
throw new Error(`@dwk/rdf: cannot store term of type "${term.termType}"`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Reconstruct an RDF term from its flat store representation. */
|
|
65
|
+
export function storedToTerm(stored: StoredTerm): Term {
|
|
66
|
+
switch (stored.termType) {
|
|
67
|
+
case "NamedNode":
|
|
68
|
+
return DataFactory.namedNode(stored.value);
|
|
69
|
+
case "BlankNode":
|
|
70
|
+
return DataFactory.blankNode(stored.value);
|
|
71
|
+
case "DefaultGraph":
|
|
72
|
+
return DataFactory.defaultGraph();
|
|
73
|
+
case "Literal":
|
|
74
|
+
if (stored.language) {
|
|
75
|
+
return DataFactory.literal(stored.value, stored.language);
|
|
76
|
+
}
|
|
77
|
+
return DataFactory.literal(
|
|
78
|
+
stored.value,
|
|
79
|
+
DataFactory.namedNode(stored.datatype ?? XSD_STRING),
|
|
80
|
+
);
|
|
81
|
+
default:
|
|
82
|
+
throw new Error(
|
|
83
|
+
`@dwk/rdf: unknown stored term type "${String(stored.termType)}"`,
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Convert a quad into its flat store representation. */
|
|
89
|
+
export function quadToStored(quad: Quad): StoredQuad {
|
|
90
|
+
return {
|
|
91
|
+
subject: termToStored(quad.subject),
|
|
92
|
+
predicate: termToStored(quad.predicate),
|
|
93
|
+
object: termToStored(quad.object),
|
|
94
|
+
graph: termToStored(quad.graph),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Reconstruct a quad from its flat store representation. */
|
|
99
|
+
export function storedToQuad(stored: StoredQuad): Quad {
|
|
100
|
+
return DataFactory.quad(
|
|
101
|
+
storedToTerm(stored.subject) as Quad["subject"],
|
|
102
|
+
DataFactory.namedNode(stored.predicate.value),
|
|
103
|
+
storedToTerm(stored.object) as Quad_Object,
|
|
104
|
+
storedToTerm(stored.graph) as Quad_Graph,
|
|
105
|
+
);
|
|
106
|
+
}
|
package/src/turtle.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Parser, Writer } from "n3";
|
|
2
|
+
import type { Quad } from "n3";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Turtle-family (Turtle / TriG / N-Triples / N-Quads) parse and serialize over
|
|
6
|
+
* N3.js. Plain-data inputs only — no Workers-runtime dependency.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Options for {@link parseTurtle}. */
|
|
10
|
+
export interface ParseTurtleOptions {
|
|
11
|
+
/**
|
|
12
|
+
* N3.js format hint (e.g. `"Turtle"`, `"TriG"`, `"N-Triples"`, `"N-Quads"`).
|
|
13
|
+
* When omitted, N3.js sniffs the format and defaults to Turtle/TriG.
|
|
14
|
+
*/
|
|
15
|
+
readonly format?: string;
|
|
16
|
+
/** Base IRI used to resolve relative IRIs in the document. */
|
|
17
|
+
readonly baseIRI?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Parse a Turtle (or N-Triples / N-Quads / TriG) document into quads. */
|
|
21
|
+
export function parseTurtle(
|
|
22
|
+
input: string,
|
|
23
|
+
options?: ParseTurtleOptions,
|
|
24
|
+
): Quad[] {
|
|
25
|
+
return new Parser({
|
|
26
|
+
format: options?.format,
|
|
27
|
+
baseIRI: options?.baseIRI,
|
|
28
|
+
}).parse(input);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Options for {@link writeTurtle}. */
|
|
32
|
+
export interface WriteTurtleOptions {
|
|
33
|
+
/**
|
|
34
|
+
* N3.js output format (e.g. `"Turtle"`, `"TriG"`, `"N-Triples"`,
|
|
35
|
+
* `"N-Quads"`). Defaults to Turtle/TriG.
|
|
36
|
+
*/
|
|
37
|
+
readonly format?: string;
|
|
38
|
+
/** Prefixes to declare in the serialized output. */
|
|
39
|
+
readonly prefixes?: Record<string, string>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Serialize quads back into a Turtle-family document. */
|
|
43
|
+
export function writeTurtle(
|
|
44
|
+
quads: Quad[],
|
|
45
|
+
options?: WriteTurtleOptions,
|
|
46
|
+
): Promise<string> {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const writer = new Writer({
|
|
49
|
+
format: options?.format,
|
|
50
|
+
prefixes: options?.prefixes,
|
|
51
|
+
});
|
|
52
|
+
writer.addQuads(quads);
|
|
53
|
+
writer.end((error, result) => (error ? reject(error) : resolve(result)));
|
|
54
|
+
});
|
|
55
|
+
}
|