useResource works

main
Ailin Luca 2 years ago
parent 6d8ff2515f
commit 3791babfa2
  1. 2
      package-lock.json
  2. 4
      packages/demo-react/src/Layout.tsx
  3. 45
      packages/demo-react/src/dashboard/BuildMainContainer.tsx
  4. 31
      packages/demo-react/src/dashboard/Dashboard.tsx
  5. 12
      packages/demo-react/src/media/MediaPage.tsx
  6. 5
      packages/demo-react/src/media/MediaPost.tsx
  7. 22
      packages/solid-react/src/useResource.ts
  8. 6
      packages/solid-react/src/util/useForceReload.ts
  9. 4
      packages/solid/src/SolidLdoDataset.ts
  10. 4
      packages/solid/src/resource/Container.ts
  11. 4
      packages/solid/src/resource/Leaf.ts
  12. 26
      packages/solid/src/resource/Resource.ts
  13. 1
      packages/solid/src/util/RequestBatcher.ts

2
package-lock.json generated

@ -46961,7 +46961,7 @@
"@ldo/solid": {
"version": "file:packages/solid",
"requires": {
"@inrupt/solid-client": "*",
"@inrupt/solid-client": "^1.30.0",
"@inrupt/solid-client-authn-core": "^1.17.1",
"@ldo/cli": "^0.0.0",
"@ldo/dataset": "^0.0.0",

@ -3,8 +3,8 @@ import React, { useState } from "react";
import type { FunctionComponent } from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { Dashboard } from "./dashboard/Dashboard";
import { Media } from "./media/Media";
import { BuildMainContainer } from "./dashboard/BuildMainContainer";
import { MediaPage } from "./media/MediaPage";
const router = createBrowserRouter([
{
@ -13,7 +13,7 @@ const router = createBrowserRouter([
},
{
path: "/media/:uri",
element: <Media />,
element: <MediaPage />,
},
]);

@ -1,10 +1,10 @@
import React, { useState, useEffect } from "react";
import type { FunctionComponent } from "react";
import type { Container, LeafUri } from "@ldo/solid";
import type { Container, ContainerUri, LeafUri } from "@ldo/solid";
import { useSolidAuth, useLdo } from "@ldo/solid-react";
export interface BuildMainContainerChildProps {
mainContainer: Container;
mainContainerUri: ContainerUri;
}
export const BuildMainContainer: FunctionComponent<{
@ -23,29 +23,28 @@ export const BuildMainContainer: FunctionComponent<{
alert(rootContainer.message);
return;
}
const mainContainer =
await rootContainer.createChildIfAbsent("demo-react/");
if (mainContainer.type === "error") {
alert(mainContainer.message);
return;
}
const mainContainer = getResource(`${rootContainer.uri}demo-react/`);
setMainContainer(mainContainer);
mainContainer.setAccessRules({
public: {
read: true,
write: false,
append: false,
control: false,
},
agent: {
[session.webId!]: {
await mainContainer.read();
if (mainContainer.isAbsent()) {
await mainContainer.createIfAbsent();
await mainContainer.setAccessRules({
public: {
read: true,
write: true,
append: true,
control: true,
write: false,
append: false,
control: false,
},
},
});
agent: {
[session.webId!]: {
read: true,
write: true,
append: true,
control: true,
},
},
});
}
});
}
}, [session.webId]);
@ -55,5 +54,5 @@ export const BuildMainContainer: FunctionComponent<{
return <p>Loading</p>;
}
return <Child mainContainer={mainContainer} />;
return <Child mainContainerUri={mainContainer.uri} />;
};

@ -1,18 +1,27 @@
import React from "react";
import type { FunctionComponent } from "react";
import type { BuildMainContainerChildProps } from "./BuildMainContainer";
import { useResource } from "@ldo/solid-react";
import { MediaPost } from "../media/MediaPost";
import { UploadButton } from "./UploadButton";
export const Dashboard: FunctionComponent<BuildMainContainerChildProps> = ({
mainContainer,
mainContainerUri,
}) => {
return <p>{mainContainer.uri}</p>;
// return (
// <div>
// <div>
// <UploadButton />
// </div>
// <hr />
// <div>{mainContainer.isLoading ? "Loading" : "Not Loading"}</div>
// </div>
// );
const mainContainer = useResource(mainContainerUri);
if (mainContainer.isLoading()) {
return <p>Loading Main Container</p>;
}
return (
<div>
<div>
<UploadButton />
</div>
<hr />
{mainContainer.children().map((child) => (
<MediaPost key={child.uri} uri={child.uri} />
))}
</div>
);
};

@ -0,0 +1,12 @@
import React from "react";
import type { FunctionComponent } from "react";
import { useParams } from "react-router-dom";
import { MediaPost } from "./MediaPost";
export const MediaPage: FunctionComponent = () => {
const { uri } = useParams();
if (!uri) {
return <p>No URI present</p>;
}
return <MediaPost uri={uri} />;
};

@ -1,12 +1,11 @@
import React from "react";
import type { FunctionComponent } from "react";
import { useParams } from "react-router-dom";
export const Media: FunctionComponent = () => {
const { uri } = useParams();
export const MediaPost: FunctionComponent<{ uri: string }> = ({ uri }) => {
return (
<div>
<p>Media: {uri}</p>
<hr />
</div>
);
};

@ -1,4 +1,4 @@
import { useMemo } from "react";
import { useMemo, useEffect, useRef } from "react";
import type {
Container,
ContainerUri,
@ -7,11 +7,25 @@ import type {
Leaf,
} from "@ldo/solid";
import { useLdo } from "./SolidLdoProvider";
import { useForceReload } from "./util/useForceReload";
export function useResource(uri: ContainerUri): Container;
export function useResource(uri: LeafUri): Leaf;
export function useResource(uri: string): Resource;
export function useResource(uri: string): Resource {
export function useResource(uri: string): Leaf | Container;
export function useResource(uri: string): Leaf | Container {
const { getResource } = useLdo();
return useMemo(() => getResource(uri), [getResource, uri]);
const resource = useMemo(() => getResource(uri), [getResource, uri]);
const pastResource = useRef<Resource | undefined>();
const forceReload = useForceReload();
useEffect(() => {
if (pastResource.current) {
pastResource.current.off("update", forceReload);
}
pastResource.current = resource;
resource.on("update", forceReload);
return () => {
resource.off("update", forceReload);
};
}, [resource]);
return resource;
}

@ -1,6 +1,6 @@
import { useState } from "react";
import { useState, useCallback } from "react";
export function useForceUpdate() {
export function useForceReload() {
const [, setValue] = useState(0);
return () => setValue((value) => value + 1);
return useCallback(() => setValue((value) => value + 1), []);
}

@ -21,8 +21,8 @@ export class SolidLdoDataset extends LdoDataset {
getResource(uri: ContainerUri, options?: ResourceGetterOptions): Container;
getResource(uri: LeafUri, options?: ResourceGetterOptions): Leaf;
getResource(uri: string, options?: ResourceGetterOptions): Resource;
getResource(uri: string, options?: ResourceGetterOptions): Resource {
getResource(uri: string, options?: ResourceGetterOptions): Leaf | Container;
getResource(uri: string, options?: ResourceGetterOptions): Leaf | Container {
return this.context.resourceStore.get(uri, options);
}
}

@ -18,12 +18,14 @@ import type { Leaf } from "./Leaf";
import { Resource } from "./Resource";
export class Container extends Resource {
readonly uri: ContainerUri;
protected requester: ContainerRequester;
protected rootContainer: boolean | undefined;
readonly type = "container" as const;
constructor(uri: ContainerUri, context: SolidLdoDatasetContext) {
super(uri, context);
super(context);
this.uri = uri;
this.requester = new ContainerRequester(uri, context);
}

@ -19,13 +19,15 @@ import type { Container } from "./Container";
import { Resource } from "./Resource";
export class Leaf extends Resource {
readonly uri: LeafUri;
protected requester: Requester;
readonly type = "leaf" as const;
protected binaryData: { data: Blob; mimeType: string } | undefined;
constructor(uri: LeafUri, context: SolidLdoDatasetContext) {
super(uri, context);
super(context);
this.uri = uri;
this.requester = new LeafRequester(uri, context);
}

@ -19,18 +19,22 @@ import type {
} from "../requester/requestResults/AccessRule";
import { getAccessRules } from "../requester/requests/getAccessRules";
import { setAccessRules } from "../requester/requests/setAccessRules";
import type TypedEmitter from "typed-emitter";
import EventEmitter from "events";
export abstract class Resource {
export abstract class Resource extends (EventEmitter as new () => TypedEmitter<{
update: () => void;
}>) {
// All intance variables
protected readonly context: SolidLdoDatasetContext;
readonly uri: string;
abstract readonly uri: string;
abstract readonly type: string;
protected abstract readonly requester: Requester;
protected didInitialFetch: boolean = false;
protected absent: boolean | undefined;
constructor(uri: string, context: SolidLdoDatasetContext) {
this.uri = uri;
constructor(context: SolidLdoDatasetContext) {
super();
this.context = context;
}
@ -74,18 +78,26 @@ export abstract class Resource {
protected parseResult<PossibleErrors extends ErrorResult>(
result: AbsentResult | BinaryResult | DataResult | PossibleErrors,
): this | PossibleErrors {
let toReturn: this | PossibleErrors;
switch (result.type) {
case "error":
return result;
toReturn = result;
break;
case "absent":
this.didInitialFetch = true;
this.absent = true;
return this;
// eslint-disable-next-line @typescript-eslint/no-this-alias
toReturn = this;
break;
default:
this.didInitialFetch = true;
this.absent = false;
return this;
// eslint-disable-next-line @typescript-eslint/no-this-alias
toReturn = this;
break;
}
this.emit("update");
return toReturn;
}
// Read Methods

@ -141,6 +141,7 @@ export class RequestBatcher {
waitingProcess as unknown as WaitingProcess<any[], any>,
);
this.loadingMap[waitingProcess.name] = true;
this.loadingMap[ANY_KEY] = true;
this.triggerOrWaitProcess();
});
}

Loading…
Cancel
Save