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", "@rdfjs/types": "^1.0.1",
"@testing-library/react": "^14.1.2", "@testing-library/react": "^14.1.2",
"@types/jest": "^27.0.3", "@types/jest": "^27.0.3",
"@types/uuid": "^10.0.0",
"jest-environment-jsdom": "^27.0.0", "jest-environment-jsdom": "^27.0.0",
"start-server-and-test": "^2.0.3", "start-server-and-test": "^2.0.3",
"ts-jest": "^27.1.2", "ts-jest": "^27.1.2",
"ts-node": "^10.9.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": { "packages/solid-type-index/node_modules/ts-jest": {
"version": "27.1.5", "version": "27.1.5",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz",

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

@ -30,6 +30,7 @@
"@rdfjs/types": "^1.0.1", "@rdfjs/types": "^1.0.1",
"@testing-library/react": "^14.1.2", "@testing-library/react": "^14.1.2",
"@types/jest": "^27.0.3", "@types/jest": "^27.0.3",
"@types/uuid": "^10.0.0",
"jest-environment-jsdom": "^27.0.0", "jest-environment-jsdom": "^27.0.0",
"start-server-and-test": "^2.0.3", "start-server-and-test": "^2.0.3",
"ts-jest": "^27.1.2", "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 RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
export const TYPE_REGISTRATION = export const TYPE_REGISTRATION =
"http://www.w3.org/ns/solid/terms#TypeRegistration"; "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"; } from "./.ldo/typeIndex.shapeTypes";
import { FOR_CLASS, RDF_TYPE, TYPE_REGISTRATION } from "./constants"; import { FOR_CLASS, RDF_TYPE, TYPE_REGISTRATION } from "./constants";
import { guaranteeOptions, type Options } from "./util/Options"; 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 type { TypeRegistration } from "./.ldo/typeIndex.typings";
import { getProfile } from "./getTypeIndex"; import { getProfile } from "./getTypeIndex";
import { TypeIndexProfileShapeType } from "./.ldo/profile.shapeTypes"; import { TypeIndexProfileShapeType } from "./.ldo/profile.shapeTypes";
import type { SolidLdoDataset } from "@ldo/solid";
import type { Container } 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); await createIndex(webId, profileFolder, dataset, true);
} }
if (!profile.publicTypeIndex?.length) { 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( export async function createIndex(
webId, webId,
profileFolder: Container, profileFolder: Container,
dataset: SolidLdoDataset, dataset: ISolidLdoDataset,
isPrivate: boolean, isPrivate: boolean,
) { ) {
// Create a private type index // Create a private type index
@ -88,19 +89,9 @@ export async function createIndex(
.write(indexResource.uri) .write(indexResource.uri)
.fromSubject(indexResource.uri); .fromSubject(indexResource.uri);
console.log(indexResource.uri, webId);
cTypeIndex.type = [{ "@id": "ListedDocument" }, { "@id": "TypeIndex" }]; 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(); const commitResult = await transaction.commitToPod();
if (commitResult.isError) { if (commitResult.isError) throw commitResult;
commitResult.errors.forEach((err) => {
if (err.type === "invalidUriError") {
console.log(err.uri);
}
});
throw commitResult;
}
} }
/** /**
@ -148,6 +139,8 @@ export async function removeRegistration(
options, options,
); );
console.log(typeRegistration["@id"]);
// Add instances to type registration // Add instances to type registration
instances.instance?.forEach((instance) => { instances.instance?.forEach((instance) => {
typeRegistration.instance?.splice( typeRegistration.instance?.splice(
@ -156,8 +149,9 @@ export async function removeRegistration(
); );
}); });
instances.instanceContainer?.forEach((instanceContainer) => { instances.instanceContainer?.forEach((instanceContainer) => {
typeRegistration.instance?.splice( console.log("Splicing instanceContainers", instanceContainer);
typeRegistration.instance.findIndex( typeRegistration.instanceContainer?.splice(
typeRegistration.instanceContainer.findIndex(
(val) => val["@id"] === instanceContainer, (val) => val["@id"] === instanceContainer,
), ),
1, 1,
@ -172,27 +166,40 @@ export function findAppropriateTypeRegistration(
) { ) {
const { dataset } = guaranteeOptions(options); const { dataset } = guaranteeOptions(options);
// Check to see if its already in the index // Check to see if its already in the index
const existingRegistrationUri: string | undefined = dataset const existingRegistrationsUris: NamedNode[] = dataset
.match( .match(
null, null,
namedNode(RDF_TYPE), namedNode(RDF_TYPE),
namedNode(TYPE_REGISTRATION), namedNode(TYPE_REGISTRATION),
namedNode(indexUri), namedNode(indexUri),
) )
.match(null, namedNode(FOR_CLASS), namedNode(classUri)) .toArray()
.toArray()[0]?.subject.value; .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; let typeRegistration: TypeRegistration;
if (existingRegistrationUri) { if (existingRegistrationForClassUri) {
typeRegistration = dataset typeRegistration = dataset
.usingType(TypeRegistrationShapeType) .usingType(TypeRegistrationShapeType)
.write(indexUri) .write(indexUri)
.fromSubject(existingRegistrationUri); .fromSubject(existingRegistrationForClassUri);
} else { } else {
typeRegistration = dataset.createData( typeRegistration = dataset
TypeRegistrationShapeType, .usingType(TypeRegistrationShapeType)
`${indexUri}#${v4()}`, .write(indexUri)
dataset.getResource(indexUri), .fromSubject(`${indexUri}#${v4()}`);
);
typeRegistration.type = { "@id": "TypeRegistration" }; typeRegistration.type = { "@id": "TypeRegistration" };
typeRegistration.forClass = { "@id": classUri }; 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"; import { guaranteeFetch } from "@ldo/solid/dist/util/guaranteeFetch";
export interface Options { export interface Options {
solidLdoDataset?: SolidLdoDataset; solidLdoDataset?: ISolidLdoDataset;
fetch?: typeof fetch; fetch?: typeof fetch;
} }

@ -2,18 +2,31 @@ import { createSolidLdoDataset } from "@ldo/solid";
import { import {
MY_BOOKMARKS_1_URI, MY_BOOKMARKS_1_URI,
MY_BOOKMARKS_2_URI, MY_BOOKMARKS_2_URI,
PRIVATE_TYPE_INDEX_URI,
PUBLIC_TYPE_INDEX_URI,
ROOT_CONTAINER,
setupEmptyTypeIndex, setupEmptyTypeIndex,
setupFullTypeIndex, setupFullTypeIndex,
setUpServer, setUpServer,
WEB_ID, WEB_ID,
} from "./setUpServer"; } from "./setUpServer";
import { getInstanceUris, getTypeRegistrations } from "../src/getTypeIndex"; 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 { 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. // Use an increased timeout, since the CSS server takes too much setup time.
jest.setTimeout(40_000); 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", () => { describe("General Tests", () => {
const s = setUpServer(); const s = setUpServer();
@ -25,7 +38,7 @@ describe("General Tests", () => {
solidLdoDataset, solidLdoDataset,
}); });
const addressBookUris = await getInstanceUris( const addressBookUris = await getInstanceUris(
"http://www.w3.org/2006/vcard/ns#AddressBook", ADDRESS_BOOK,
typeRegistrations, typeRegistrations,
{ solidLdoDataset }, { solidLdoDataset },
); );
@ -35,11 +48,9 @@ describe("General Tests", () => {
"https://example.com/myPublicAddressBook.ttl", "https://example.com/myPublicAddressBook.ttl",
]), ]),
); );
const bookmarkUris = await getInstanceUris( const bookmarkUris = await getInstanceUris(BOOKMARK, typeRegistrations, {
"http://www.w3.org/2002/01/bookmark#Bookmark", solidLdoDataset,
typeRegistrations, });
{ solidLdoDataset },
);
expect(bookmarkUris).toEqual( expect(bookmarkUris).toEqual(
expect.arrayContaining([MY_BOOKMARKS_1_URI, MY_BOOKMARKS_2_URI]), expect.arrayContaining([MY_BOOKMARKS_1_URI, MY_BOOKMARKS_2_URI]),
); );
@ -55,9 +66,73 @@ describe("General Tests", () => {
const profile = solidLdoDataset const profile = solidLdoDataset
.usingType(TypeIndexProfileShapeType) .usingType(TypeIndexProfileShapeType)
.fromSubject(WEB_ID); .fromSubject(WEB_ID);
console.log(solidLdoDataset.toString());
expect(profile.privateTypeIndex?.["@id"]).toBeDefined(); expect(profile.privateTypeIndex?.[0]?.["@id"]).toBeDefined();
expect(profile.publicTypeIndex?.["@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 type { ReadResultError } from "./requester/requests/readResource";
import { ProfileWithStorageShapeType } from "./.ldo/solid.shapeTypes"; import { ProfileWithStorageShapeType } from "./.ldo/solid.shapeTypes";
import type { GetStorageContainerFromWebIdSuccess } from "./requester/results/success/CheckRootContainerSuccess"; 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 * 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"); * .fromSubject("https://example.com/profile#me");
* ``` * ```
*/ */
export class SolidLdoDataset extends LdoDataset { export class SolidLdoDataset extends LdoDataset implements ISolidLdoDataset {
/** /**
* @internal * @internal
*/ */

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

@ -27,3 +27,5 @@ export * from "./resource/wac/results/GetWacRuleSuccess";
export * from "./resource/wac/results/GetWacUriSuccess"; export * from "./resource/wac/results/GetWacUriSuccess";
export * from "./resource/wac/results/SetWacRuleSuccess"; export * from "./resource/wac/results/SetWacRuleSuccess";
export * from "./resource/wac/results/WacRuleAbsent"; 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 { ResourceGetterOptions } from "./ResourceStore";
import type { Container } from "./resource/Container"; import type { Container } from "./resource/Container";
import type { Leaf } from "./resource/Leaf"; import type { Leaf } from "./resource/Leaf";
import type { ContainerUri, LeafUri } from "./util/uriTypes"; import type { ContainerUri, LeafUri } from "./util/uriTypes";
import type { SolidLdoTransactionDataset } from "./SolidLdoTransactionDataset";
/** /**
* A SolidLdoDataset provides methods for getting Solid resources. * 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: ContainerUri, options?: ResourceGetterOptions): Container;
getResource(uri: LeafUri, options?: ResourceGetterOptions): Leaf; getResource(uri: LeafUri, options?: ResourceGetterOptions): Leaf;
getResource(uri: string, options?: ResourceGetterOptions): Leaf | Container; getResource(uri: string, options?: ResourceGetterOptions): Leaf | Container;

Loading…
Cancel
Save