diff --git a/package-lock.json b/package-lock.json
index 5cf16ef..99e23da 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/packages/demo-react/src/Layout.tsx b/packages/demo-react/src/Layout.tsx
index 109bddb..fd811a4 100644
--- a/packages/demo-react/src/Layout.tsx
+++ b/packages/demo-react/src/Layout.tsx
@@ -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: ,
+ element: ,
},
]);
diff --git a/packages/demo-react/src/dashboard/BuildMainContainer.tsx b/packages/demo-react/src/dashboard/BuildMainContainer.tsx
index d9c29de..2429325 100644
--- a/packages/demo-react/src/dashboard/BuildMainContainer.tsx
+++ b/packages/demo-react/src/dashboard/BuildMainContainer.tsx
@@ -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
Loading
;
}
- return ;
+ return ;
};
diff --git a/packages/demo-react/src/dashboard/Dashboard.tsx b/packages/demo-react/src/dashboard/Dashboard.tsx
index fe9f6af..4eb5c37 100644
--- a/packages/demo-react/src/dashboard/Dashboard.tsx
+++ b/packages/demo-react/src/dashboard/Dashboard.tsx
@@ -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 = ({
- mainContainer,
+ mainContainerUri,
}) => {
- return {mainContainer.uri}
;
- // return (
- //
- //
- //
- //
- //
- //
{mainContainer.isLoading ? "Loading" : "Not Loading"}
- //
- // );
+ const mainContainer = useResource(mainContainerUri);
+ if (mainContainer.isLoading()) {
+ return Loading Main Container
;
+ }
+
+ return (
+
+
+
+
+
+ {mainContainer.children().map((child) => (
+
+ ))}
+
+ );
};
diff --git a/packages/demo-react/src/media/MediaPage.tsx b/packages/demo-react/src/media/MediaPage.tsx
new file mode 100644
index 0000000..fc113f1
--- /dev/null
+++ b/packages/demo-react/src/media/MediaPage.tsx
@@ -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 No URI present
;
+ }
+ return ;
+};
diff --git a/packages/demo-react/src/media/Media.tsx b/packages/demo-react/src/media/MediaPost.tsx
similarity index 53%
rename from packages/demo-react/src/media/Media.tsx
rename to packages/demo-react/src/media/MediaPost.tsx
index b39949e..32fb4ab 100644
--- a/packages/demo-react/src/media/Media.tsx
+++ b/packages/demo-react/src/media/MediaPost.tsx
@@ -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 (
);
};
diff --git a/packages/solid-react/src/useResource.ts b/packages/solid-react/src/useResource.ts
index bfe048a..8a8d48a 100644
--- a/packages/solid-react/src/useResource.ts
+++ b/packages/solid-react/src/useResource.ts
@@ -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();
+ 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;
}
diff --git a/packages/solid-react/src/util/useForceReload.ts b/packages/solid-react/src/util/useForceReload.ts
index 7535f7a..6082c84 100644
--- a/packages/solid-react/src/util/useForceReload.ts
+++ b/packages/solid-react/src/util/useForceReload.ts
@@ -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), []);
}
diff --git a/packages/solid/src/SolidLdoDataset.ts b/packages/solid/src/SolidLdoDataset.ts
index b3f7f29..75c5003 100644
--- a/packages/solid/src/SolidLdoDataset.ts
+++ b/packages/solid/src/SolidLdoDataset.ts
@@ -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);
}
}
diff --git a/packages/solid/src/resource/Container.ts b/packages/solid/src/resource/Container.ts
index 0088214..2591eeb 100644
--- a/packages/solid/src/resource/Container.ts
+++ b/packages/solid/src/resource/Container.ts
@@ -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);
}
diff --git a/packages/solid/src/resource/Leaf.ts b/packages/solid/src/resource/Leaf.ts
index d9c062b..b9faa97 100644
--- a/packages/solid/src/resource/Leaf.ts
+++ b/packages/solid/src/resource/Leaf.ts
@@ -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);
}
diff --git a/packages/solid/src/resource/Resource.ts b/packages/solid/src/resource/Resource.ts
index 9b72b1a..64e4b11 100644
--- a/packages/solid/src/resource/Resource.ts
+++ b/packages/solid/src/resource/Resource.ts
@@ -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(
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
diff --git a/packages/solid/src/util/RequestBatcher.ts b/packages/solid/src/util/RequestBatcher.ts
index 084b47b..3f0a287 100644
--- a/packages/solid/src/util/RequestBatcher.ts
+++ b/packages/solid/src/util/RequestBatcher.ts
@@ -141,6 +141,7 @@ export class RequestBatcher {
waitingProcess as unknown as WaitingProcess,
);
this.loadingMap[waitingProcess.name] = true;
+ this.loadingMap[ANY_KEY] = true;
this.triggerOrWaitProcess();
});
}