You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
Jackson Morgan 44575669e5 Encountering errors in tests 10 months ago
..
src Encountering errors in tests 10 months ago
test Encountering errors in tests 10 months ago
.eslintrc Created rdf-utils 2 years ago
LICENSE.txt Update Readmes 2 years ago
README.md Added some documentation 2 years ago
babel.config.js fix tests for v7 upgrade 1 year ago
jest.config.js fix tests for v7 upgrade 1 year ago
package.json Encountering errors in tests 10 months ago
tsconfig.build.json Update Readmes 2 years ago
typedoc.json Added some documentation 2 years ago

README.md

@ldo/solid

@ldo/solid is a client that implements the Solid specification with the use of Linked Data Objects.

Installation

Navigate into your project's root folder and run the following command:

cd my_project/
npx run @ldo/cli init

Now install the @ldo/solid library

npm i @ldo/solid

Manual Installation

If you already have generated ShapeTypes, you may install the @ldo/ldo and @ldo/solid libraries independently.

npm i @ldo/ldo @ldo/solid

Simple Examples

Below is a simple example of @ldo/solid. Assume that a ShapeType was previously generated and placed at ./.ldo/foafProfile.shapeTypes. Also assume we have a shape type for social media at ./.ldo/socialMediaPost.shapeTypes

import { changeData, commitData, createSolidLdoDataset } from "@ldo/solid";
import { fetch, getDefaultSession } from "@inrupt/solid-client-authn-browser";
import { FoafProfileShapeType } from "./.ldo/foafProfile.shapeTypes";
import { SocialMediaPostShapeType } from "./.ldo/socialMediaPost.shapeTypes";

async function main() {
  /**
   * ===========================================================================
   * READING DATA FROM A POD
   * ===========================================================================
   */

  // Before we begin using @ldo/solid. Let's get the WebId of the current user
  const webIdUri = getDefaultSession().info.webId;
  if (!webIdUri) throw new Error("User is not logged in");

  // Now let's proceed with @ldo/solid. Our first step is setting up a
  // SolidLdoDataset. You can think of this dataset as a local store for all the
  // information in the Solidverse. Don't forget to pass the authenticated fetch
  // function to do your queries!
  const solidLdoDataset = createSolidLdoDataset({ fetch });

  // We'll start with getting a representation of our WebId's resource
  const webIdResource = solidLdoDataset.getResource(webIdUri);

  // This resource is currently unfetched
  console.log(webIdResource.isUnfetched()); // Logs true

  // So let's fetch it! Running the `read` command will make a request to get
  // the WebId.
  const readResult = await webIdResource.read();

  // @ldo/solid will never throw an error. Instead, it will return errors. This
  // design decision was made to force you to handle any errors. It may seem a
  // bit annoying at first, but it will result in more resiliant code. You can
  // easily follow intellisense tooltips to see what kinds of errors each action
  // can throw.
  if (readResult.isError) {
    switch (readResult.type) {
      case "serverError":
        console.error("The solid server had an error:", readResult.message);
        return;
      case "noncompliantPodError":
        console.error("The Pod responded in a way not compliant with the spec");
        return;
      default:
        console.error("Some other error was detected:", readResult.message);
    }
  }

  // When fetching a data resource, read triples will automatically be added to
  // the solidLdoDataset. You can access them using Linked Data Objects. In
  // the following example we're using a Profile Linked Data Object that was
  // generated with the init step.
  const profile = solidLdoDataset
    .usingType(FoafProfileShapeType)
    .fromSubject(webIdUri);

  // Now you can read "profile" like any JSON.
  console.log(profile.name);

  /**
   * ===========================================================================
   * MODIFYING DATA
   * ===========================================================================
   */

  // When we want to modify data the first step is to use the `changeData`
  // function. We pass in an object that we want to change (in this case,
  // "profile") as well an a list of any resources to which we want those
  // changes to be applied (in this case, just the webIdResource). This gives
  // us a new variable (conventionally named with a c for "changed") that we can
  // write changes to.
  const cProfile = changeData(profile, webIdResource);

  // We can make changes just like it's regular JSON
  cProfile.name = "Captain Cool Dude";

  // Committing data is as easy as running the "commitData" function.
  const commitResult = await commitData(cProfile);

  // Remember to check for and handle errors! We'll keep it short this time.
  if (commitResult.isError) throw commitResult;

  /**
   * ===========================================================================
   * CREATING NEW RESOURCES
   * ===========================================================================
   */

  // Let's create some social media posts to be stored on the Solid Pod!
  // Our first step is going to be finding where to place these posts. In the
  // future, there will be advanced ways to determine the location of resources
  // but for now, let's throw it in the root folder.

  // But, first, let's find out where the root folder is. We can take our WebId
  // resource and call `getRootContainer`. Let's assume the root container has
  // a URI "https://example.com/"
  const rootContainer = await webIdResource.getRootContainer();
  if (rootContainer.isError) throw rootContainer;

  // Now, let's create a container for our posts
  const createPostContainerResult =
    await rootContainer.createChildIfAbsent("social-posts/");
  if (createPostContainerResult.isError) throw createPostContainerResult;

  // Most results store the affected resource in the "resource" field. This
  // container has the URI "https://example.com/social-posts/"
  const postContainer = createPostContainerResult.resource;

  // Now that we have our container, let's make a Post resource! This is a data
  // resource, which means we can put raw Solid Data (RDF) into it.
  const postResourceResult =
    await postContainer.createChildAndOverwrite("post1.ttl");
  if (postResourceResult.isError) throw postResourceResult;
  const postResource = postResourceResult.resource;

  // We can also create binary resources with things like images
  const imageResourceResult = await postContainer.uploadChildAndOverwrite(
    // name of the binary
    "image1.svg",
    // A blob for the binary
    new Blob([`<svg><circle r="9" /></svg>`]),
    // mime type of the binary
    "image/svg+xml",
  );
  if (imageResourceResult.isError) throw imageResourceResult;
  const imageResource = imageResourceResult.resource;

  /**
   * ===========================================================================
   * CREATING NEW DATA
   * ===========================================================================
   */

  // We create data in a similar way to the way we modify data. We can use the
  // "createData" method.
  const cPost = solidLdoDataset.createData(
    // An LDO ShapeType saying that this is a social media psot
    SocialMediaPostShapeType,
    // The URI of the post (in this case we'll make it the same as the resource)
    postResource.uri,
    // The resource we should write it to
    postResource,
  );

  // We can add new data
  cPost.text = "Check out this bad svg:";
  cPost.image = { "@id": imageResource.uri };

  // And now we commit data
  const newDataResult = await commitData(cPost);
  if (newDataResult.isError) throw newDataResult;

  /**
   * ===========================================================================
   * DELETING RESOURCES
   * ===========================================================================
   */

  // Deleting resources can be done with a single method call. In this case,
  // the container will be deleted along with all its contained resources
  const deleteResult = await postContainer.delete();
  if (deleteResult.isError) throw deleteResult;
}
main();

API Details

SolidLdoDataset

Resources (Manage batching requests)

Standalone Functions

Data Functions

Sponsorship

This project was made possible by a grant from NGI Zero Entrust via nlnet. Learn more on the NLnet project page.

nlnet foundation logo NGI Zero Entrust Logo

Liscense

MIT