Complete type-index

main
Jackson Morgan 8 months ago
parent 483cd69db9
commit 02b2d90f2a
  1. 8
      package-lock.json
  2. 1
      packages/ldo/src/index.ts
  3. 1
      packages/solid-type-index/package.json
  4. 5
      packages/solid-type-index/src/constants.ts
  5. 61
      packages/solid-type-index/src/setTypeIndex.ts
  6. 5
      packages/solid-type-index/src/util/Options.ts
  7. 95
      packages/solid-type-index/test/General.test.tsx
  8. 3
      packages/solid/src/SolidLdoDataset.ts
  9. 14
      packages/solid/src/SolidLdoTransactionDataset.ts
  10. 2
      packages/solid/src/index.ts
  11. 6
      packages/solid/src/types.ts

8
package-lock.json generated

@ -29746,12 +29746,20 @@
"@rdfjs/types": "^1.0.1",
"@testing-library/react": "^14.1.2",
"@types/jest": "^27.0.3",
"@types/uuid": "^10.0.0",
"jest-environment-jsdom": "^27.0.0",
"start-server-and-test": "^2.0.3",
"ts-jest": "^27.1.2",
"ts-node": "^10.9.2"
}
},
"packages/solid-type-index/node_modules/@types/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
"dev": true,
"license": "MIT"
},
"packages/solid-type-index/node_modules/ts-jest": {
"version": "27.1.5",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz",

@ -7,3 +7,4 @@ export * from "./LdoBuilder";
export * from "./createLdoDataset";
import type { LdoBase as LdoBaseImport } from "./util";
export type LdoBase = LdoBaseImport;
export * from "./types";

@ -30,6 +30,7 @@
"@rdfjs/types": "^1.0.1",
"@testing-library/react": "^14.1.2",
"@types/jest": "^27.0.3",
"@types/uuid": "^10.0.0",
"jest-environment-jsdom": "^27.0.0",
"start-server-and-test": "^2.0.3",
"ts-jest": "^27.1.2",

@ -1,4 +1,7 @@
export const RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
export const TYPE_REGISTRATION =
"http://www.w3.org/ns/solid/terms#TypeRegistration";
export const FOR_CLASS = "http://www.w3.org/2006/vcard/ns#forClass";
export const FOR_CLASS = "http://www.w3.org/ns/solid/terms#forClass";
export const INSTANCE = "http://www.w3.org/ns/solid/terms#instance";
export const INSTANCE_CONTAINER =
"http://www.w3.org/ns/solid/terms#instanceContainer";

@ -5,12 +5,13 @@ import {
} from "./.ldo/typeIndex.shapeTypes";
import { FOR_CLASS, RDF_TYPE, TYPE_REGISTRATION } from "./constants";
import { guaranteeOptions, type Options } from "./util/Options";
import { namedNode } from "@rdfjs/data-model";
import { namedNode, quad } from "@rdfjs/data-model";
import type { TypeRegistration } from "./.ldo/typeIndex.typings";
import { getProfile } from "./getTypeIndex";
import { TypeIndexProfileShapeType } from "./.ldo/profile.shapeTypes";
import type { SolidLdoDataset } from "@ldo/solid";
import type { Container } from "@ldo/solid";
import type { ISolidLdoDataset } from "@ldo/solid";
import type { NamedNode } from "@rdfjs/types";
/**
* =============================================================================
@ -32,7 +33,7 @@ export async function initTypeIndex(
await createIndex(webId, profileFolder, dataset, true);
}
if (!profile.publicTypeIndex?.length) {
await createIndex(webId, profileFolder, dataset, true);
await createIndex(webId, profileFolder, dataset, false);
}
}
}
@ -46,7 +47,7 @@ export async function initTypeIndex(
export async function createIndex(
webId,
profileFolder: Container,
dataset: SolidLdoDataset,
dataset: ISolidLdoDataset,
isPrivate: boolean,
) {
// Create a private type index
@ -88,19 +89,9 @@ export async function createIndex(
.write(indexResource.uri)
.fromSubject(indexResource.uri);
console.log(indexResource.uri, webId);
cTypeIndex.type = [{ "@id": "ListedDocument" }, { "@id": "TypeIndex" }];
console.log("added", transaction.getChanges().added?.toString());
console.log("removed", transaction.getChanges().added?.toString());
const commitResult = await transaction.commitToPod();
if (commitResult.isError) {
commitResult.errors.forEach((err) => {
if (err.type === "invalidUriError") {
console.log(err.uri);
}
});
throw commitResult;
}
if (commitResult.isError) throw commitResult;
}
/**
@ -148,6 +139,8 @@ export async function removeRegistration(
options,
);
console.log(typeRegistration["@id"]);
// Add instances to type registration
instances.instance?.forEach((instance) => {
typeRegistration.instance?.splice(
@ -156,8 +149,9 @@ export async function removeRegistration(
);
});
instances.instanceContainer?.forEach((instanceContainer) => {
typeRegistration.instance?.splice(
typeRegistration.instance.findIndex(
console.log("Splicing instanceContainers", instanceContainer);
typeRegistration.instanceContainer?.splice(
typeRegistration.instanceContainer.findIndex(
(val) => val["@id"] === instanceContainer,
),
1,
@ -172,27 +166,40 @@ export function findAppropriateTypeRegistration(
) {
const { dataset } = guaranteeOptions(options);
// Check to see if its already in the index
const existingRegistrationUri: string | undefined = dataset
const existingRegistrationsUris: NamedNode[] = dataset
.match(
null,
namedNode(RDF_TYPE),
namedNode(TYPE_REGISTRATION),
namedNode(indexUri),
)
.match(null, namedNode(FOR_CLASS), namedNode(classUri))
.toArray()[0]?.subject.value;
.toArray()
.map((quad) => quad.subject) as NamedNode[];
const existingRegistrationForClassUri = existingRegistrationsUris.find(
(registrationUri) => {
return dataset.has(
quad(
registrationUri,
namedNode(FOR_CLASS),
namedNode(classUri),
namedNode(indexUri),
),
);
},
)?.value;
let typeRegistration: TypeRegistration;
if (existingRegistrationUri) {
if (existingRegistrationForClassUri) {
typeRegistration = dataset
.usingType(TypeRegistrationShapeType)
.write(indexUri)
.fromSubject(existingRegistrationUri);
.fromSubject(existingRegistrationForClassUri);
} else {
typeRegistration = dataset.createData(
TypeRegistrationShapeType,
`${indexUri}#${v4()}`,
dataset.getResource(indexUri),
);
typeRegistration = dataset
.usingType(TypeRegistrationShapeType)
.write(indexUri)
.fromSubject(`${indexUri}#${v4()}`);
typeRegistration.type = { "@id": "TypeRegistration" };
typeRegistration.forClass = { "@id": classUri };
}

@ -1,8 +1,9 @@
import { createSolidLdoDataset, type SolidLdoDataset } from "@ldo/solid";
import { createSolidLdoDataset } from "@ldo/solid";
import type { ISolidLdoDataset } from "@ldo/solid";
import { guaranteeFetch } from "@ldo/solid/dist/util/guaranteeFetch";
export interface Options {
solidLdoDataset?: SolidLdoDataset;
solidLdoDataset?: ISolidLdoDataset;
fetch?: typeof fetch;
}

@ -2,18 +2,31 @@ import { createSolidLdoDataset } from "@ldo/solid";
import {
MY_BOOKMARKS_1_URI,
MY_BOOKMARKS_2_URI,
PRIVATE_TYPE_INDEX_URI,
PUBLIC_TYPE_INDEX_URI,
ROOT_CONTAINER,
setupEmptyTypeIndex,
setupFullTypeIndex,
setUpServer,
WEB_ID,
} from "./setUpServer";
import { getInstanceUris, getTypeRegistrations } from "../src/getTypeIndex";
import { initTypeIndex } from "../src/setTypeIndex";
import {
addRegistration,
initTypeIndex,
removeRegistration,
} from "../src/setTypeIndex";
import { TypeIndexProfileShapeType } from "../src/.ldo/profile.shapeTypes";
import { namedNode } from "@rdfjs/dataset";
import { INSTANCE } from "../src/constants";
// Use an increased timeout, since the CSS server takes too much setup time.
jest.setTimeout(40_000);
const ADDRESS_BOOK = "http://www.w3.org/2006/vcard/ns#AddressBook";
const BOOKMARK = "http://www.w3.org/2002/01/bookmark#Bookmark";
const EXAMPLE_THING = "https://example.com/ExampleThing";
describe("General Tests", () => {
const s = setUpServer();
@ -25,7 +38,7 @@ describe("General Tests", () => {
solidLdoDataset,
});
const addressBookUris = await getInstanceUris(
"http://www.w3.org/2006/vcard/ns#AddressBook",
ADDRESS_BOOK,
typeRegistrations,
{ solidLdoDataset },
);
@ -35,11 +48,9 @@ describe("General Tests", () => {
"https://example.com/myPublicAddressBook.ttl",
]),
);
const bookmarkUris = await getInstanceUris(
"http://www.w3.org/2002/01/bookmark#Bookmark",
typeRegistrations,
{ solidLdoDataset },
);
const bookmarkUris = await getInstanceUris(BOOKMARK, typeRegistrations, {
solidLdoDataset,
});
expect(bookmarkUris).toEqual(
expect.arrayContaining([MY_BOOKMARKS_1_URI, MY_BOOKMARKS_2_URI]),
);
@ -55,9 +66,73 @@ describe("General Tests", () => {
const profile = solidLdoDataset
.usingType(TypeIndexProfileShapeType)
.fromSubject(WEB_ID);
console.log(solidLdoDataset.toString());
expect(profile.privateTypeIndex?.["@id"]).toBeDefined();
expect(profile.publicTypeIndex?.["@id"]).toBeDefined();
expect(profile.privateTypeIndex?.[0]?.["@id"]).toBeDefined();
expect(profile.publicTypeIndex?.[0]?.["@id"]).toBeDefined();
});
it("Adds to the typeIndex", async () => {
await setupFullTypeIndex(s);
const solidLdoDataset = createSolidLdoDataset();
await getTypeRegistrations(WEB_ID, { solidLdoDataset });
const transaction = solidLdoDataset.startTransaction();
addRegistration(
PUBLIC_TYPE_INDEX_URI,
ADDRESS_BOOK,
{ instance: ["https://example.com/AdressBook3"] },
{ solidLdoDataset: transaction },
);
addRegistration(
PRIVATE_TYPE_INDEX_URI,
EXAMPLE_THING,
{ instanceContainer: ["https://example.com/ExampleInstance"] },
{ solidLdoDataset: transaction },
);
const { added, removed } = transaction.getChanges();
const existingRegistration = namedNode(
"http://localhost:3003/example/profile/publicTypeIndex.ttl#ab09fd",
);
expect(removed).not.toBeDefined();
expect(added?.size).toBe(4);
expect(added?.match(existingRegistration).size).toBe(1);
expect(
added?.match(
existingRegistration,
namedNode(INSTANCE),
namedNode("https://example.com/AdressBook3"),
namedNode("http://localhost:3003/example/profile/publicTypeIndex.ttl"),
).size,
).toBe(1);
});
it("Removes from the typeIndex", async () => {
await setupFullTypeIndex(s);
const solidLdoDataset = createSolidLdoDataset();
await getTypeRegistrations(WEB_ID, { solidLdoDataset });
const transaction = solidLdoDataset.startTransaction();
removeRegistration(
PUBLIC_TYPE_INDEX_URI,
ADDRESS_BOOK,
{ instance: ["https://example.com/myPublicAddressBook.ttl"] },
{ solidLdoDataset: transaction },
);
removeRegistration(
PRIVATE_TYPE_INDEX_URI,
BOOKMARK,
{ instanceContainer: [`${ROOT_CONTAINER}myBookmarks/`] },
{ solidLdoDataset: transaction },
);
const { added, removed } = transaction.getChanges();
expect(added).not.toBeDefined();
expect(removed?.size).toBe(2);
});
});

@ -15,6 +15,7 @@ import type { NoRootContainerError } from "./requester/results/error/NoRootConta
import type { ReadResultError } from "./requester/requests/readResource";
import { ProfileWithStorageShapeType } from "./.ldo/solid.shapeTypes";
import type { GetStorageContainerFromWebIdSuccess } from "./requester/results/success/CheckRootContainerSuccess";
import type { ISolidLdoDataset } from "./types";
/**
* A SolidLdoDataset has all the functionality of an LdoDataset with the added
@ -41,7 +42,7 @@ import type { GetStorageContainerFromWebIdSuccess } from "./requester/results/su
* .fromSubject("https://example.com/profile#me");
* ```
*/
export class SolidLdoDataset extends LdoDataset {
export class SolidLdoDataset extends LdoDataset implements ISolidLdoDataset {
/**
* @internal
*/

@ -14,7 +14,6 @@ import {
updateDatasetInBulk,
type ITransactionDatasetFactory,
} from "@ldo/subscribable-dataset";
import type { SolidLdoDataset } from "./SolidLdoDataset";
import type { AggregateSuccess } from "./requester/results/success/SuccessResult";
import type { ResourceResult } from "./resource/resourceResult/ResourceResult";
import type {
@ -75,7 +74,7 @@ export class SolidLdoTransactionDataset
* @param initialDataset - A set of triples to initialize this dataset
*/
constructor(
parentDataset: SolidLdoDataset,
parentDataset: ISolidLdoDataset,
context: SolidLdoDatasetContext,
datasetFactory: DatasetFactory,
transactionDatasetFactory: ITransactionDatasetFactory<Quad>,
@ -108,6 +107,15 @@ export class SolidLdoTransactionDataset
return this.context.resourceStore.get(uri, options);
}
public startTransaction(): SolidLdoTransactionDataset {
return new SolidLdoTransactionDataset(
this,
this.context,
this.datasetFactory,
this.transactionDatasetFactory,
);
}
async commitToPod(): Promise<
| AggregateSuccess<
ResourceResult<UpdateSuccess | UpdateDefaultGraphSuccess, Leaf>
@ -117,8 +125,6 @@ export class SolidLdoTransactionDataset
const changes = this.getChanges();
const changesByGraph = splitChangesByGraph(changes);
console.log(changesByGraph);
// Iterate through all changes by graph in
const results: [
GraphNode,

@ -27,3 +27,5 @@ export * from "./resource/wac/results/GetWacRuleSuccess";
export * from "./resource/wac/results/GetWacUriSuccess";
export * from "./resource/wac/results/SetWacRuleSuccess";
export * from "./resource/wac/results/WacRuleAbsent";
export * from "./types";

@ -1,12 +1,16 @@
import type { ILdoDataset } from "@ldo/ldo";
import type { ResourceGetterOptions } from "./ResourceStore";
import type { Container } from "./resource/Container";
import type { Leaf } from "./resource/Leaf";
import type { ContainerUri, LeafUri } from "./util/uriTypes";
import type { SolidLdoTransactionDataset } from "./SolidLdoTransactionDataset";
/**
* A SolidLdoDataset provides methods for getting Solid resources.
*/
export interface ISolidLdoDataset {
export interface ISolidLdoDataset extends ILdoDataset {
startTransaction(): SolidLdoTransactionDataset;
getResource(uri: ContainerUri, options?: ResourceGetterOptions): Container;
getResource(uri: LeafUri, options?: ResourceGetterOptions): Leaf;
getResource(uri: string, options?: ResourceGetterOptions): Leaf | Container;

Loading…
Cancel
Save