Added comments for the LDO library

main
jaxoncreed 2 years ago
parent 92a9a57f28
commit b955d3bdec
  1. 10
      package-lock.json
  2. 2
      packages/ldo/README.md
  3. 7
      packages/ldo/package.json
  4. 187
      packages/ldo/src/LdoBuilder.ts
  5. 21
      packages/ldo/src/LdoDataset.ts
  6. 18
      packages/ldo/src/LdoDatasetFactory.ts
  7. 47
      packages/ldo/src/ShapeType.ts
  8. 28
      packages/ldo/src/createLdoDataset.ts
  9. 332
      packages/ldo/src/methods.ts
  10. 24
      packages/ldo/src/parseRdf.ts
  11. 5
      packages/ldo/src/util.ts
  12. 6
      packages/ldo/typedoc.json
  13. 3
      packages/solid/typedoc.json

10
package-lock.json generated

@ -33893,7 +33893,9 @@
"cross-fetch": "^3.1.5",
"jest": "^27.4.5",
"ts-jest": "^27.1.2",
"ts-node": "^10.4.0"
"ts-node": "^10.4.0",
"typedoc": "^0.25.4",
"typedoc-plugin-markdown": "^3.17.1"
}
},
"packages/ldo/node_modules/ts-jest": {
@ -44609,7 +44611,9 @@
"jest": "^27.4.5",
"readable-stream": "^4.3.0",
"ts-jest": "^27.1.2",
"ts-node": "^10.4.0"
"ts-node": "^10.4.0",
"typedoc": "^0.25.4",
"typedoc-plugin-markdown": "^3.17.1"
},
"dependencies": {
"ts-jest": {
@ -46290,7 +46294,7 @@
"@ldo/solid-react": {
"version": "file:packages/solid-react",
"requires": {
"@inrupt/jest-jsdom-polyfills": "*",
"@inrupt/jest-jsdom-polyfills": "^3.0.2",
"@inrupt/solid-client": "^1.29.0",
"@inrupt/solid-client-authn-browser": "^1.17.1",
"@inrupt/solid-client-authn-core": "^1.17.1",

@ -115,7 +115,7 @@ Types
- [`LdoBase`](https://ldo.js.org/api/ldo/LdoBase/)
- [`ShapeType`](https://ldo.js.org/api/ldo/ShapeType/)
Getting a LdoDataset
Getting an LdoDataset
- [`parseRdf`](https://ldo.js.org/api/ldo/parseRdf/)
- [`createLdoDatasetFactory`](https://ldo.js.org/api/ldo/createLdoDatasetFactory/)

@ -9,7 +9,8 @@
"test": "jest --coverage",
"test:watch": "jest --watch --coverage",
"prepublishOnly": "npm run test && npm run build",
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern"
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern",
"docs": "typedoc --plugin typedoc-plugin-markdown"
},
"repository": {
"type": "git",
@ -32,7 +33,9 @@
"cross-fetch": "^3.1.5",
"jest": "^27.4.5",
"ts-jest": "^27.1.2",
"ts-node": "^10.4.0"
"ts-node": "^10.4.0",
"typedoc": "^0.25.4",
"typedoc-plugin-markdown": "^3.17.1"
},
"dependencies": {
"@ldo/dataset": "^0.0.1-alpha.17",

@ -8,13 +8,37 @@ import type { LdoBase } from "./util";
import { normalizeNodeName, normalizeNodeNames } from "./util";
/**
* A wrapper around Jsonld Dataset Proxy Builder with a slightly more friendly
* user experience that doesn't require the use of rdfjs datatypes.
* An LdoBuilder contains utility methods for building a Linked Data Object for a certain type.
*
* It is not recommended to instantiate an LdoDataset. Instead use the {@link createLdoDataset} function.
*
* @typeParam Type - The TypeScript type of the eventual Linked Data Object.
*
* @example
* ```typescript
* import { LdoDataset, createLdoDatasetFactory } from "@ldo/ldo";
* import { FoafProfileShapeType } from "./.ldo/foafProfile.shapeTypes";
*
* const ldoDataset = createLdoDataset();
* const ldoBuilder = ldoDataset.usingType(FoafProfileShapeType);
* const profile = ldoBuilder
* .write("https://example.com/someGraph")
* .fromSubject("https://example.com/profile#me");
* ```
*/
export class LdoBuilder<Type extends LdoBase> {
/**
* @internal
*/
private jsonldDatasetProxyBuilder: JsonldDatasetProxyBuilder;
private shapeType: ShapeType<Type>;
/**
* Initializes the LdoBuilder
*
* @param jsonldDatasetProxyBuilder - A base JsonldDatasetProxyBuilder that thios LdoBuilder wraps
* @param shapeType - The ShapeType for this builder
*/
constructor(
jsonldDatasetProxyBuilder: JsonldDatasetProxyBuilder,
shapeType: ShapeType<Type>,
@ -24,34 +48,18 @@ export class LdoBuilder<Type extends LdoBase> {
}
/**
* Designates that all Linked Data Objects created should write to the
* specified graphs
*/
write(...graphs: (GraphNode | string)[]): LdoBuilder<Type> {
return new LdoBuilder(
this.jsonldDatasetProxyBuilder.write(...normalizeNodeNames(graphs)),
this.shapeType,
);
}
/**
* Sets the order of language preferences for Language Strings. Acceptable
* values as EITF language tags, "@none" and "@other"
*/
setLanguagePreferences(
...languageOrdering: LanguageOrdering
): LdoBuilder<Type> {
return new LdoBuilder(
this.jsonldDatasetProxyBuilder.setLanguagePreferences(
...languageOrdering,
),
this.shapeType,
);
}
/**
* Creates a Linked Data Object that matches the given subject
* @param subject The node to match
* `fromSubject` lets you define a an `entryNode`, the place of entry for the graph. The object returned by `jsonldDatasetProxy` will represent the given node. This parameter accepts both `namedNode`s and `blankNode`s. `fromSubject` takes a generic type representing the typescript type of the given subject.
*
* @param subject - The node to match
*
* @returns A Linked Data Object for the provided subject.
*
* @example
* ```typescript
* const profile = ldoDataset
* .usingType(FoafProfileShapeType)
* .fromSubject("http://example.com/Person1");
* ```
*/
fromSubject(subject: SubjectNode | string): Type {
return this.jsonldDatasetProxyBuilder.fromSubject<Type>(
@ -60,11 +68,26 @@ export class LdoBuilder<Type extends LdoBase> {
}
/**
* Matches Subjects to provided predicates, objects, and graphs. Returns a
* JSON LD Dataset that can be read an modified.
* @param predicate The predicate to match
* @param object The object to match
* @param graph The graph to match
* `matchSubject` returns a Jsonld Dataset Proxy representing all subjects in the dataset matching the given predicate, object, and graph.
*
* @param predicate - A valid Predicate Node (NamedNode) or a string URI.
* @param object - A valid object node (NamedNode, Blank Node, or Literal) or a string URI.
* @param graph - A valid graph node (NamedNode or DefaultGraph) or a string URI.
*
* @returns A Linked Data Object Array with all subjects the match the provided nodes.
*
* @example
* ```typescript
* const profiles = ldoDataset
* .usingType(FoafProfileShapeType)
* .matchSubject(
* namedNode("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"),
* namedNode("http://xmlns.com/foaf/0.1/Person")
* );
* profiles.forEach((person) => {
* console.log(person.fn);
* });
* ```
*/
matchSubject(
predicate: QuadMatch[1] | string,
@ -79,11 +102,22 @@ export class LdoBuilder<Type extends LdoBase> {
}
/**
* Matches Objects to provided subjects, predicates, and graphs. Returns a
* collection of Linked Data Objects that can be read an modified.
* @param subject The subject to match
* @param predicate The predicate to match
* @param graph The graph to match
* `matchObject` returns a Jsonld Dataset Proxy representing all objects in the dataset matching the given subject, predicate, and graph.
*
* @param subject - A valid object node (NamedNode or Blank Node) or a string URI.
* @param predicate - A valid Predicate Node (NamedNode) or a string URI.
* @param graph - A valid graph node (NamedNode or DefaultGraph) or a string URI.
*
* @returns A Linked Data Object Array with all objects the match the provided nodes.
*
* @example
* ```typescript
* matchObject(
* subject?: SubjectNode | string,
* predicate?: PredicateNode | string,
* graph?: GraphNode | string,
* ): Type[]
* ```
*/
matchObject(
subject?: QuadMatch[0] | string,
@ -98,13 +132,78 @@ export class LdoBuilder<Type extends LdoBase> {
}
/**
* Takes a given object and places it in the dataset while returning a Linked
* Data Object representing the object.
* `fromJson` will take any regular Json, add the information to the dataset, and return a Jsonld Dataset Proxy representing the given data.
*
* @param inputData - Initial data matching the type
* @returns A linked data object or linked data object array depending on the input
*
* @param inputData Initial Data
* @param graph Optional graph to save this data to
* @example
* ```typescript
* const person2 = ldoDataset
* .usingType(FoafProfileShapeType)
* .fromJson({
* "@id": "http://example.com/Person2",
* fn: ["Jane Doe"],
* });
* ```
*/
fromJson(inputData: Type): Type {
return this.jsonldDatasetProxyBuilder.fromJson<Type>(inputData);
}
/**
* Designates that all Linked Data Objects created should write to the specified graphs. By default, all new quads are added to the default graph, but you can change the graph to which new quads are added.
*
* NOTE: These operations only dictate the graph for new triples. Any operations that delete triples will delete triples regardless of their graph.
*
* @param graphs - any number of Graph Nodes or string URIs that all add operations will be put in.
*
* @returns An LdoBuilder for constructor chaining
*
* @example
* ```typescript
* const person1 = ldoDataset.usingType(FoafShapeType)
* .write(namedNode("http://example.com/ExampleGraph"))
* .fromSubject(namedNode("http://example.com/Person1"));
* person1.name.push("Jack");
* console.log(dataset.toString());
* // Logs:
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "Jack" <http://example.com/ExampleGraph> .
* ```
*/
write(...graphs: (GraphNode | string)[]): LdoBuilder<Type> {
return new LdoBuilder(
this.jsonldDatasetProxyBuilder.write(...normalizeNodeNames(graphs)),
this.shapeType,
);
}
/**
* Sets the order of language preferences for Language Strings. Acceptable values are EITF language tags, "@none" and "@other"
*
* @param languageOrdering - The order languages will be selected. Acceptable values are EITF language tags, "@none" and "@other".
*
* @returns An LdoBuilder for constructor chaining
*
* @example
* ```typescript
* // Read Spansih first, then Korean, then language strings with no language
* // New writes are in Spanish
* ["es", "ko", "@none"]
*
* // Read any language other than french, then french
* // New writes are in French
* ["@other", "fr"]
* ```
*/
setLanguagePreferences(
...languageOrdering: LanguageOrdering
): LdoBuilder<Type> {
return new LdoBuilder(
this.jsonldDatasetProxyBuilder.setLanguagePreferences(
...languageOrdering,
),
this.shapeType,
);
}
}

@ -6,12 +6,27 @@ import type { ShapeType } from "./ShapeType";
import type { LdoBase } from "./index";
/**
* Utility for building a linked data object
* @category Getting an LdoDataset
*
* An LdoDataset is a utility for building a linked data object.
*
* It is not recommended to instantiate an LdoDataset. Instead use the {@link createLdoDataset} function.
*
* @example
* ```typescript
* import { LdoDataset, createLdoDatasetFactory } from "@ldo/ldo";
* import { FoafProfileShapeType } from "./.ldo/foafProfile.shapeTypes";
*
* const ldoDatasetFactory = createLdoDatasetFactory();
* const ldoDataset = new LdoDataset();
* const ldoBuilder = ldoDataset.usingType(FoafProfileShapeType);
* ```
*/
export class LdoDataset extends WrapperSubscribableDataset<Quad> {
/**
* Gets a builder for a given type
* @param shapeType A ShapeType
* Creates an LdoBuilder for a given shapeType
*
* @param shapeType - A ShapeType
* @returns A builder for the given type
*/
public usingType<Type extends LdoBase>(

@ -2,14 +2,26 @@ import type { DatasetFactory, Dataset, Quad } from "@rdfjs/types";
import { LdoDataset } from "./LdoDataset";
/**
* A DatasetFactory that creates an ExtendedDataset given a DatasetCoreFactory.
* @category Getting an LdoDataset
* `LdoDatasetFactory` is a helper class that includes methods for creating LdoDatasets.
*
* This class exists for parity with RDF/JS. Most developers will not use it. Instead, it's better to use {@link createLdoDataset}.
*
* @example
* ```typescript
* import { createLdoDatasetFactory } from "ldo";
*
* const datasetFactory = // some RDF/JS Dataset Factory
* const ldoDatasetFactory = new LdoDatasetFactory(datasetFactory);
* const ldoDataset = ldoDatasetFactory.dataset(initialDataset);
* ```
*/
export class LdoDatasetFactory implements DatasetFactory<Quad, Quad> {
private datasetFactory: DatasetFactory<Quad, Quad>;
/**
* @constructor
* @param datasetFactory A generic dataset factory this factory will wrap
* @param datasetFactory - A generic dataset factory this factory will wrap
*/
constructor(datasetFactory: DatasetFactory<Quad, Quad>) {
this.datasetFactory = datasetFactory;
@ -17,7 +29,7 @@ export class LdoDatasetFactory implements DatasetFactory<Quad, Quad> {
/**
* Creates an LdoDataset
* @param quads A list of quads to initialize the dataset
* @param quads - A list of quads to initialize the dataset
* @returns an LdoDataset
*/
dataset(quads?: Dataset<Quad, Quad> | Quad[]): LdoDataset {

@ -3,13 +3,54 @@ import type { Schema } from "shexj";
import type { LdoBase } from "./util";
/**
* A collection of information required by LDO
* @category Types
*
* A `ShapeType` is an interface that contains information required by LDO to create a Linked Data Object. ShapeTypes are generated by the `@ldo/cli` `build` command, and it contains the following data:
*
* - ShEx Schema
* - Generated Typescript Typings
* - Generated Context
*
* @example
* The following is the ShapeType generated for the example `FoafProfile.shex` file.
* ```typescript
* import { ShapeType } from "ldo";
* import { foafProfileSchema } from "./foafProfile.schema";
* import { foafProfileContext } from "./foafProfile.context";
* import { FoafProfile } from "./foafProfile.typings";
*
* export const FoafProfileShapeType: ShapeType<FoafProfile> = {
* schema: foafProfileSchema,
* shape: "https://example.com/FoafProfile",
* context: foafProfileContext,
* };
* ```
*
* This can be imported and used to create a Linked Data Object.
* ```typescript
* import { FoafProfileShapeType } from "./.ldo/foafProfile.shapeTypes";
* import { FoafProfile } from "./.ldo/foafProfile.typings";
*
* const profile: FoafProfile = ldoDataset
* .usingType(FoafProfileShapeType)
* .fromSubject("https://example.com/profile.ttl#me");
* ```
*/
export type ShapeType<Type extends LdoBase> = {
/**
* The ShEx Schema
*/
schema: Schema;
/**
* The key of the shape within the schema to which this ShapeType refers
*/
shape: string;
/**
* A JSON-LD context generated for this Schema
*/
context: ContextDefinition;
// This field is optional. It's main point is to allow the typescript parser to
// understand that this shape type is of a specific type.
/**
* This field is optional and the `@ldo/cli` `build` command will not provide this field. The `exampleData` field's primary purpose is to force the TypeScript parser to recognize the provided `Type` so it can be auto-inferenced in the `LdoDataset.usingType` method.
*/
exampleData?: Type;
};

@ -4,8 +4,17 @@ import { LdoDatasetFactory } from "./LdoDatasetFactory";
import type { LdoDataset } from "./LdoDataset";
/**
* Creates an LDO Dataset Factory
* @category Getting an LdoDataset
*
* A helper function that creates an LdoDatasetFactory.
* This function exists for parity with RDF/JS. Most developers will not use it. Instead, it's better to use {@link createLdoDataset}.
*
* @returns An LDO Dataset Factory
*
* @example
* ```typescript
* createLdoDatasetFactory(): Promise<LdoDatasetFactory>
* ```
*/
export function createLdoDatasetFactory() {
const datasetFactory: DatasetFactory<Quad> = {
@ -17,9 +26,20 @@ export function createLdoDatasetFactory() {
}
/**
* Create an LDO Dataset
* @param initialDataset
* @returns An LDO Dataset
* @category Getting an LdoDataset
*
* A function that initializes an LdoDataset.
*
* @param initialDataset - An optional dataset or array of quads for the new dataset
*
* @returns An LDO Dataset initialized with the intitial dataset if any
*
* @example
* ```typescript
* import { createLdoDataset } from "@ldo/ldo";
*
* const ldoDataset = createLdoDataset();
* ```
*/
export function createLdoDataset(
initialDataset?: Dataset<Quad, Quad> | Quad[],

@ -18,19 +18,216 @@ import {
normalizeNodeNames,
} from "./util";
export {
graphOf,
languagesOf,
setLanguagePreferences,
import {
graphOf as graphOfImport,
languagesOf as languagesOfImport,
setLanguagePreferences as setLanguagePreferencesImport,
} from "@ldo/jsonld-dataset-proxy";
/**
* The graph of specific information can be detected using the `graphOf(subject, predicate, object)` function.
*
* @param subject - A Linked Data Object that represents the subject of a quad.
* @param predicate - A field on the given Linked Data Object
* @param object - An optional parameter that represents the direct object of a statement. This could be a Linked Data Object or a number to indicate the location in an array. This argument can be left blank if the given field is not an array.
*
* @returns A GraphNode (defaultGraph or namedNode).
*
* @example
* ```typescript
* import { graphOf } from "@ldo/ldo";
* graphOf(person, "name", 0); // returns defaultGraph()
* graphOf(person, "age"); // returns defaultGraph()
* ```
*/
export const graphOf = graphOfImport;
/**
* The `languageOf` function lets you view and modify the language strings directly. `languageOf` takes two properties:
*
* It returns a mapping of languages to strings or sets of strings depending on the cardinality of the JSON-LD context.
*
* @param ldo - Any Linked Data Object
* @param field - Any field on the provided Linked Data Object
*
* @returns `languageOf` returns either a `LanguageSetMap` if the given field is an array, or a `LanguageMap` if the given field is a singular value. For example, `languageOf(profile, "friends")` would return a `LanguageSetMap` because there the `listOfFriendNames` field has a cardinality over 1, but `languageOf(profile, "familyName")` would return a `LanguageMap` because it has a cardinality of 1.
*
* @example
* This example uses a `LanguageMap`. The `LanguageMap` is a mapping between various language tags (including the `@none` tag) and the singular language value for that tag. Modifying the `LanguageMap` will automatically update the underlying dataset.
* ```typescript
* const labelLanguages = languagesOf(hospitalInfo, "label");
* // labelLanguages: { '@none': 'Hospital', fr: 'Hôpital', ko: '병원' }
* // logs "병원"
* console.log(labelLanguages.ko);
* // Adds a Chinese label
* labelLanguages.zh = "医院";
* // Changes the no-language label from to "Super Hospital"
* labelLanguages["@none"] = "Super Hospital";
* // Removes the French label
* delete labelLanguages.fr;
* ```
* @example
* This example uses a `LanguageSetMap` The `LanguageSetMap` is a mapping between various language tags (including the `@none` tag) and a JavaScript Set of all values for that tag. Modifying the `LanguageSetMap` will automatically update the underlying dataset.
* ```typescript
* const descriptionLanguages = languagesOf(hospitalInfo, "description");
* // descriptionLanguages:
* // {
* // '@none': Set(2) { 'Heals patients', 'Has doctors' },
* // fr: Set(2) { 'Guérit les malades', 'A des médecins' },
* // ko: Set(2) { '환자를 치료하다', '의사 있음' }
* // }
* // Logs: 환자를 치료하다\n의사 있음
* Array.from(descriptionLanguages.ko).forEach((str) => console.log(str));
* // Adds a Hindi description
* descriptionLanguages.hi?.add("रिक करत");
* // Checks to see if the korean label contains "의사 있음"
* descriptionLanguages.ko?.has("의사 있음"); // returns true
* // Removes "Has Doctors" from the no-language description
* descriptionLanguages["@none"]?.delete("Has Doctors");
* ```
*/
export const languagesOf = languagesOfImport;
/**
* A language preference is an ordered list telling the Linked Data Object the language you prefer as well as callbacks.
*
* For read operations, the Linked Data Object will search for values in order of the preference. Write operations will choose the first language in the language preference, unless that language is `@other`, in which case it will choose the next language.
*
* @example
* A language ordering is an ordering of preferred languages. Valid values for the language preferences includes any [IETF Language Tag](https://en.wikipedia.org/wiki/IETF_language_tag) as well as the special tags `@none` and `@other`. `@none` represents any language literal that doesn't have a language tag. `@other` represents any language literal that isn't listed among the language preferences.
*
* ```typescript
* // Read Spansih first, then Korean, then language strings with no language
* // New writes are in Spanish
* ["es", "ko", "@none"]
*
* // Read any language other than french, then french
* // New writes are in French
* ["@other", "fr"]
* ```
*
* @example
* The `setLanguagePreferences(...).using(...)` function sets the language preferences for a set of Linked Data Objects.
*
* ```typescript
* import { setLanguagePreferences } from "@ldo/ldo";
*
* setLanguagePreferences("fr", "ko").using(hospitalInfo);
* console.log(hospitalInfo.label); // Logs "Hôpital"
* setLanguagePreferences("@none").using(hospitalInfo);
* console.log(hospitalInfo.label); // Logs "Hospital"
* ```
*
* @example
* The `setLanguagePreferences(...).usingCopy(...)` function returns a copy of the provided Linked Data Objects with the given language preferences.
*
* ```typescript
* import { setLanguagePreferences } from "@ldo/ldo";
*
* // ...
*
* const [frenchPreference] = setLanguagePreferences("fr").usingCopy(hospitalInfo);
* const [koreanPreference] = setLanguagePreferences("ko").usingCopy(hospitalInfo);
* console.log(frenchPreference.label); // Logs "Hôpital"
* console.log(koreanPreference.label); // Logs "병원"
* ```
*/
export const setLanguagePreferences = setLanguagePreferencesImport;
/**
* By default, all new quads are added to the default graph, but you can change the graph to which new quads are added using the `write` function.
*
* @example
* The `write(...).using(...)` function lets you define the graphs you wish to write to using specific jsonldDatasetProxies.
*
* ```typescript
* import { write } from "@ldo/ldo";
*
* // Now all additions with person1 will be on ExampleGraph1
* write(namedNode("http://example.com/ExampleGraph1")).using(person1);
* person1.name.push("Jack");
* // Now all additions with person1 will be on ExampleGraph2
* write(namedNode("http://example.com/ExampleGraph2")).using(person1);
* person1.name.push("Spicer");
*
* console.log(dataset.toString());
* // Logs:
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "Jack" <http://example.com/ExampleGraph1> .
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "Spicer" <http://example.com/ExampleGraph2> .
* ```
*
* The function also returns an `end` function that will reset the graph to what it was before. This is useful for nesting graph modifications.
*
* ```typescript
* person1.name.push("default");
* const end1 = write(namedNode("http://example.com/Graph1")).using(person1);
* person1.name.push("1");
* const end2 = write(namedNode("http://example.com/Graph2")).using(person1);
* person1.name.push("2");
* const end3 = write(namedNode("http://example.com/Graph3")).using(person1);
* person1.name.push("3");
* end3();
* person1.name.push("2 again");
* end2();
* person1.name.push("1 again");
* end1();
* person1.name.push("default again");
* console.log(dataset.toString());
* // Logs:
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "default" .
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "default again" .
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "1" <http://example.com/Graph1> .
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "1 again" <http://example.com/Graph1> .
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "2" <http://example.com/Graph2> .
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "2 again" <http://example.com/Graph2> .
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "3" <http://example.com/Graph3> .
* ```
* @example
* If you would like a new variable to write to without modifying the original Jsonld Dataset Proxy, you can use `write(...).usingCopy(...)`.
*
* ```typescript
* const [person1WritingToNewGraph] = write(
* namedNode("http://example.com/NewGraph")
* ).usingCopy(person1);
* person1WritingToNewGraph.name.push("Brandon");
* person1.name.push("Sanderson");
* console.log(dataset.toString());
* // Logs:
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "Brandon" <http://example.com/NewGraph> .
* // <http://example.com/Person1> <http://xmlns.com/foaf/0.1/name> "Sanderson" .
* ```
*/
export function write(...graphs: (GraphNode | string)[]): InteractOptions {
return writeDependency(...normalizeNodeNames(graphs));
}
/**
* Begins a transaction for the given linked data object
* @param ldo
* Begins a transaction for a Linked Data Object. After this function is run, the Linked Data Object is considered to be "transactable" where all modifications are not written to the underlying dataset are stored separately as a delta.
*
* Note: If a Linked Data Object is "transactable", it cannot be passed into `startTransaction` a second time.
*
* @param ldo - Any linked data object that is not currently "transactable"
*
* @example
* ```typescript
* import {
* startTransaction,
* transactionChanges,
* toSparqlUpdate,
* commitTransaction,
* } from "@ldo/ldo";
*
* // ... Get the profile linked data object
*
* startTransaction(profile);
* profile.name = "Kuzon"
* const changes = transactionChanges(profile));
* // Logs: <https://example.com/aang> <http://xmlns.com/foaf/0.1/name> "Kuzon"
* console.log(changes.added?.toString())
* // Logs: <https://example.com/aang> <http://xmlns.com/foaf/0.1/name> "Aang"
* console.log(changes.removed?.toString())
* commitTransaction(profile);
* ```
*/
export function startTransaction(ldo: LdoBase): void {
const proxy = getProxyFromObject(ldo);
@ -45,8 +242,30 @@ export function startTransaction(ldo: LdoBase): void {
}
/**
* Ends a transaction and commits the
* @param ldo
* Commits a transaction, writing all the stored changes to the underlying dataset. After this function is run, the Linked Data Object is considered to be NOT "transactable" all further modifications will be written directly to the underlying dataset.
*
* @param ldo - Any linked data object that is currently "transactable"
*
* @example
* ```typescript
* import {
* startTransaction,
* transactionChanges,
* toSparqlUpdate,
* commitTransaction,
* } from "@ldo/ldo";
*
* // ... Get the profile linked data object
*
* startTransaction(profile);
* profile.name = "Kuzon"
* const changes = transactionChanges(profile));
* // Logs: <https://example.com/aang> <http://xmlns.com/foaf/0.1/name> "Kuzon"
* console.log(changes.added?.toString())
* // Logs: <https://example.com/aang> <http://xmlns.com/foaf/0.1/name> "Aang"
* console.log(changes.removed?.toString())
* commitTransaction(profile);
* ```
*/
export function commitTransaction(ldo: LdoBase): void {
const [dataset, proxy] = getTransactionalDatasetFromLdo(ldo);
@ -57,22 +276,93 @@ export function commitTransaction(ldo: LdoBase): void {
});
}
/**
* Returns the changes that are made on a "transactable" Linked Data Object.
*
* @param ldo - Any linked data object that is currently "transactable"
*
* @returns Dataset changes with all quads added during this transaction and all quads removed during this transaction
*
* @example
* ```typescript
* import {
* startTransaction,
* transactionChanges,
* toSparqlUpdate,
* commitTransaction,
* } from "@ldo/ldo";
*
* // ... Get the profile linked data object
*
* startTransaction(profile);
* profile.name = "Kuzon"
* const changes = transactionChanges(profile));
* // Logs: <https://example.com/aang> <http://xmlns.com/foaf/0.1/name> "Kuzon"
* console.log(changes.added?.toString())
* // Logs: <https://example.com/aang> <http://xmlns.com/foaf/0.1/name> "Aang"
* console.log(changes.removed?.toString())
* commitTransaction(profile);
* ```
*/
export function transactionChanges(ldo: LdoBase): DatasetChanges<Quad> {
const [dataset] = getTransactionalDatasetFromLdo(ldo);
return dataset.getChanges();
}
/**
* Returns the Linked Data Object's underlying RDFJS dataset. Modifying this dataset will change the Linked Data Object as well.
*
* @param ldo - The Linked Data Object from which the RDFJS dataset should be extracted.
*
* @returns An RDFJS dataset
*
* @example
* ```typescript
* import { getDataset } from "@ldo/ldo"
* const dataset = getDataset(profile);
* ```
*/
export function getDataset(ldo: LdoBase): Dataset {
const proxy = getProxyFromObject(ldo);
return proxy[_getUnderlyingDataset];
}
/**
* Converts a "transactable" Linked Data Object (A Linked Data Object that has been passed as a parameter to the `startTransaction` function) to a SPARQL/Update string.
*
* @param ldo - Any linked data object that is currently "transactable"
*
* @returns A SPARQL Update string
*/
export async function toSparqlUpdate(ldo: LdoBase): Promise<string> {
const [dataset] = getTransactionalDatasetFromLdo(ldo);
const changes = dataset.getChanges();
return changesToSparqlUpdate(changes);
}
/**
* Converts a Linked Data Object to a string representation based on a provided configuration.
*
* @param ldo - Any linked data object
* @param options - WriterOptions from N3
* @param options.format - `string | MimeFormat | undefined` The name of the format to serialize.
* @param options.prefixes - `Prefixes<RDF.NamedNode | string> | - undefined` A list of prefixes that should be in the document.
*
* @returns Serialized N3 RDF
*
* @example
* ```typescript
* import { serialize } from "@ldo/ldo"
* // ...
* const rawTurtle: string = await serialize(profile, {
* format: "Turtle",
* prefixes: {
* ex: "https://example.com/",
* foaf: "http://xmlns.com/foaf/0.1/",
* }
* });
* ```
*/
export async function serialize(
ldo: LdoBase,
options: WriterOptions,
@ -81,6 +371,19 @@ export async function serialize(
return datasetToString(dataset, options);
}
/**
* Converts a Linked Data Object to a Turtle string
*
* @param ldo - Any linked data object
* @returns Serialized Turtle
*
* @example
* ```typescript
* import { toTurtle } from "@ldo/ldo"
* // ...
* const rawTurtle: string = await toTurtle(profile);
* ```
*/
export async function toTurtle(ldo: LdoBase): Promise<string> {
const dataset = getProxyFromObject(ldo)[_getUnderlyingDataset];
return datasetToString(dataset, {});
@ -90,6 +393,19 @@ export async function toJsonLd(_ldo: LdoBase): Promise<JsonLdDocument> {
throw new Error("Not Implemented");
}
/**
* Converts a Linked Data Object to a NTriples string
*
* @param ldo - Any linked data object
* @returns An N-Triple string
*
* @example
* ```typescript
* import { toNTriples } from "@ldo/ldo"
* // ...
* const rawNTriples: string = await toNTriples(profile);
* ```
*/
export async function toNTriples(ldo: LdoBase): Promise<string> {
const dataset = getProxyFromObject(ldo)[_getUnderlyingDataset];
return datasetToString(dataset, { format: "N-Triples" });

@ -1,10 +1,32 @@
import type { Dataset } from "@rdfjs/types";
import type { JsonLdDocument } from "jsonld";
import type { ParserOptions } from "@ldo/rdf-utils";
import type { ParserOptions } from "n3";
import { createDatasetFromSerializedInput } from "@ldo/dataset";
import { createLdoDataset, createLdoDatasetFactory } from "./createLdoDataset";
import type { LdoDataset } from "./LdoDataset";
/**
* @category Getting an LdoDataset
*
* Parses raw RDF and puts its results into an LdoDataset.
*
* @param data - The raw data to parse as a `string`.
* @param parserOptions - Parser options from n3
* @param parserOptions.format - The format the data is in. The following are acceptable formats: `Turtle`, `TriG`, `N-Triples`, `N-Quads`, `N3`, `Notation3`.
* @param parserOptions.baseIRI - If this data is hosted at a specific location, you can provide the baseIRI of that location.
* @param parserOptions.blankNodePrefix - If blank nodes should have a prefix, that should be provided here.
* @param parserOptions.factory - a RDF Data Factory from [`@rdfjs/data-model`](https://www.npmjs.com/package/@rdfjs/data-model).
*
* @returns An LdoDataset containing the parsed triples
*
* @example
* ```typescript
* import { parseRdf } from "ldo";
*
* const rawTurtle = "...";
* const ldoDataset = parseRdf(rawTurtle, { baseIRI: "https://example.com/" });
* ```
*/
export async function parseRdf(
data: string | JsonLdDocument | Dataset,
parserOptions?: ParserOptions,

@ -12,7 +12,10 @@ import type {
TransactionalDataset,
} from "@ldo/subscribable-dataset";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
/**
* @category Types
* `LdoBase` is an interface defining that a Linked Data Object is a JavaScript Object Literal.
*/
export type LdoBase = Record<string, any>;
/**

@ -0,0 +1,6 @@
{
"entryPoints": ["src/index.ts"],
"out": "docs",
"allReflectionsHaveOwnDocument": true,
"hideInPageTOC": true
}

@ -1,5 +1,6 @@
{
"entryPoints": ["src/index.ts"],
"out": "docs",
"allReflectionsHaveOwnDocument": true
"allReflectionsHaveOwnDocument": true,
"hideInPageTOC": true
}
Loading…
Cancel
Save