Updated solid-react to follow the new subscription in solid

main
Jackson Morgan 8 months ago
parent eae933b7f5
commit b42ed2dbf3
  1. 12
      packages/solid-react/src/useResource.ts
  2. 27
      packages/solid-react/test/Integration.test.tsx
  3. 18
      packages/solid/src/resource/notifications/NotificationSubscription.ts

@ -40,6 +40,7 @@ export function useResource(
options?: UseResourceOptions,
): Leaf | Container | undefined {
const { getResource } = useLdo();
const subscriptionIdRef = useRef<string | undefined>();
// Get the resource
const resource = useMemo(() => {
@ -65,12 +66,15 @@ export function useResource(
useEffect(() => {
if (options?.subscribe) {
resource?.subscribeToNotifications();
} else {
resource?.unsubscribeFromNotifications();
resource
?.subscribeToNotifications()
.then((subscriptionId) => (subscriptionIdRef.current = subscriptionId));
} else if (subscriptionIdRef.current) {
resource?.unsubscribeFromNotifications(subscriptionIdRef.current);
}
return () => {
resource?.unsubscribeFromNotifications();
if (subscriptionIdRef.current)
resource?.unsubscribeFromNotifications(subscriptionIdRef.current);
};
}, [resource, options?.subscribe]);

@ -372,7 +372,10 @@ describe("Integration Tests", () => {
it("rerenders when asked to subscribe to a resource", async () => {
const NotificationTest: FunctionComponent = () => {
const resource = useResource(SAMPLE_DATA_URI, { subscribe: true });
const [isSubscribed, setIsSubscribed] = useState(true);
const resource = useResource(SAMPLE_DATA_URI, {
subscribe: isSubscribed,
});
const post = useSubject(PostShShapeType, `${SAMPLE_DATA_URI}#Post1`);
const addPublisher = useCallback(async () => {
@ -389,12 +392,16 @@ describe("Integration Tests", () => {
return (
<div>
<p role="resource">
{resource.isSubscribedToNotifications().toString()}
</p>
<ul role="list">
{post.publisher.map((publisher) => {
return <li key={publisher["@id"]}>{publisher["@id"]}</li>;
})}
</ul>
<button onClick={addPublisher}>Add Publisher</button>
<button onClick={() => setIsSubscribed(false)}>Unsubscribe</button>
</div>
);
};
@ -404,15 +411,17 @@ describe("Integration Tests", () => {
</UnauthenticatedSolidLdoProvider>,
);
const list = await screen.findByRole("list");
expect(list.children[0].innerHTML).toBe("https://example.com/Publisher1");
expect(list.children[1].innerHTML).toBe("https://example.com/Publisher2");
// Wait for subscription to connect
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
});
const list = await screen.findByRole("list");
expect(list.children[0].innerHTML).toBe("https://example.com/Publisher1");
expect(list.children[1].innerHTML).toBe("https://example.com/Publisher2");
const resourceP = await screen.findByRole("resource");
expect(resourceP.innerHTML).toBe("true");
// Click button to add a publisher
await fireEvent.click(screen.getByText("Add Publisher"));
await screen.findByText("https://example.com/Publisher3");
@ -423,11 +432,11 @@ describe("Integration Tests", () => {
"https://example.com/Publisher3",
);
unmount();
await fireEvent.click(screen.getByText("Unsubscribe"));
const resourcePUpdated = await screen.findByRole("resource");
expect(resourcePUpdated.innerHTML).toBe("false");
await act(async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
});
unmount();
});
});

@ -19,7 +19,7 @@ export abstract class NotificationSubscription {
protected parentSubscription: (message: NotificationMessage) => void;
protected context: SolidLdoDatasetContext;
protected subscriptions: Record<string, SubscriptionCallbacks> = {};
protected isOpen: boolean = false;
private isOpen: boolean = false;
constructor(
resource: Resource,
@ -52,7 +52,7 @@ export abstract class NotificationSubscription {
this.subscriptions[subscriptionId] = subscriptionCallbacks ?? {};
if (!this.isOpen) {
await this.open();
this.isOpen = true;
this.setIsOpen(true);
}
return subscriptionId;
}
@ -67,7 +67,7 @@ export abstract class NotificationSubscription {
Object.keys(this.subscriptions).length === 1
) {
await this.close();
this.isOpen = false;
this.setIsOpen(false);
}
delete this.subscriptions[subscriptionId];
}
@ -128,7 +128,17 @@ export abstract class NotificationSubscription {
onNotificationError?.(message);
});
if (message.type === "disconnectedNotAttemptingReconnectError") {
this.isOpen = false;
this.setIsOpen(false);
}
}
/**
* @internal
* setIsOpen
*/
protected setIsOpen(status: boolean) {
const shouldUpdate = status === this.isOpen;
this.isOpen = status;
if (shouldUpdate) this.resource.emit("update");
}
}

Loading…
Cancel
Save