Before risky request refactor

main
jaxoncreed 2 years ago
parent e632fa7b4d
commit 1237625c7c
  1. 2
      packages/solid-react/package.json
  2. 4
      packages/solid-react/src/useResource.ts
  3. 63
      packages/solid-react/test/Integration.test.tsx
  4. 1
      packages/solid-react/test/setUpServer.ts
  5. 1
      packages/solid/src/requester/BatchedRequester.ts
  6. 2
      packages/solid/src/resource/Resource.ts
  7. 15
      packages/solid/src/util/RequestBatcher.ts
  8. 2
      packages/solid/test/Integration.test.ts

@ -13,7 +13,7 @@
"lint": "eslint src/** --fix --no-error-on-unmatched-pattern",
"test:integration": "start-server-and-test start-test-server http://localhost:3001 start-integration-test",
"start-test-server": "ts-node ./test/test-server/runServer.ts",
"start-integration-test": "jest --coverage"
"start-integration-test": "jest --coverage -t \"Reloads the data on mount\""
},
"repository": {
"type": "git",

@ -42,12 +42,15 @@ export function useResource(
// Get the resource
const resource = useMemo(() => {
console.log(uri);
if (uri) {
const resource = getResource(uri);
// Run read operations if necissary
if (!options?.suppressInitialRead) {
if (options?.reloadOnMount) {
console.log("Reading again");
resource.read();
console.log(resource.isLoading());
} else {
resource.readIfUnfetched();
}
@ -70,6 +73,7 @@ export function useResource(
},
[resource],
);
useEffect(() => {
// Remove listeners for the previous resource
if (pastResource.current?.resource) {

@ -1,6 +1,6 @@
import React from "react";
import React, { useEffect, useState } from "react";
import type { FunctionComponent } from "react";
import { render, screen } from "@testing-library/react";
import { render, screen, fireEvent } from "@testing-library/react";
import { SAMPLE_DATA_URI, setUpServer } from "./setUpServer";
import { UnauthenticatedSolidLdoProvider } from "../src/UnauthenticatedSolidLdoProvider";
import { useResource } from "../src/useResource";
@ -32,5 +32,64 @@ describe("Integration Tests", () => {
const resourceStatus = await screen.findByRole("status");
expect(resourceStatus.innerHTML).toBe("dataReadSuccess");
});
it("returns undefined when no uri is provided, then rerenders when one is", async () => {
const UseResourceUndefinedTest: FunctionComponent = () => {
const [uri, setUri] = useState<string | undefined>(undefined);
const resource = useResource(uri, { suppressInitialRead: true });
if (!resource)
return (
<div>
<p>Undefined</p>
<button onClick={() => setUri(SAMPLE_DATA_URI)}>Next</button>
</div>
);
return <p role="status">{resource.status.type}</p>;
};
render(
<UnauthenticatedSolidLdoProvider>
<UseResourceUndefinedTest />
</UnauthenticatedSolidLdoProvider>,
);
await screen.findByText("Undefined");
fireEvent.click(screen.getByText("Next"));
const resourceStatus = await screen.findByRole("status");
expect(resourceStatus.innerHTML).toBe("unfetched");
});
});
it("Reloads the data on mount", async () => {
const ReloadTest: FunctionComponent = () => {
const resource = useResource(SAMPLE_DATA_URI, { reloadOnMount: true });
if (resource?.isLoading()) return <p>Loading</p>;
return <p role="status">{resource.status.type}</p>;
};
const ReloadParent: FunctionComponent = () => {
const [showComponent, setShowComponent] = useState(true);
return (
<div>
<button onClick={() => setShowComponent(!showComponent)}>
Show Component
</button>
{showComponent ? <ReloadTest /> : <p>Hidden</p>}
</div>
);
};
render(
<UnauthenticatedSolidLdoProvider>
<ReloadParent />
</UnauthenticatedSolidLdoProvider>,
);
await screen.findByText("Loading");
const resourceStatus1 = await screen.findByRole("status");
expect(resourceStatus1.innerHTML).toBe("dataReadSuccess");
console.log("==============");
fireEvent.click(screen.getByText("Show Component"));
await screen.findByText("Hidden");
console.log("++++++++++++++");
fireEvent.click(screen.getByText("Show Component"));
await screen.findByText("Loading");
const resourceStatus2 = await screen.findByRole("status");
expect(resourceStatus2.innerHTML).toBe("dataReadSuccess");
});
});

@ -80,7 +80,6 @@ export function setUpServer(): SetUpServerReturn {
slug: TEST_CONTAINER_SLUG,
},
});
console.log("Created container", result.status);
await Promise.all([
s.authFetch(TEST_CONTAINER_URI, {
method: "POST",

@ -55,6 +55,7 @@ export abstract class BatchedRequester {
* @returns true if the resource is making any requests
*/
isLoading(): boolean {
console.log("In isLoading");
return this.requestBatcher.isLoading(ANY_KEY);
}

@ -325,7 +325,9 @@ export abstract class Resource extends (EventEmitter as new () => TypedEmitter<{
* @returns ReadResult
*/
protected async handleRead(): Promise<ReadContainerResult | ReadLeafResult> {
console.log("Handle read");
const result = await this.requester.read();
console.log("End Handle Read");
this.status = result;
if (result.isError) return result;
this.updateWithReadSuccess(result);

@ -89,6 +89,9 @@ export class RequestBatcher {
* @returns true if the batcher is currently working on the provided process
*/
public isLoading(key: string): boolean {
console.log("In Is loadin:", key);
console.log("CurrentlyProcessing:", this.currentlyProcessing);
if (key === ANY_KEY) return !!this.currentlyProcessing;
return this.currentlyProcessing?.name === key;
}
@ -113,22 +116,31 @@ export class RequestBatcher {
const timeSinceLastTrigger = Date.now() - lastRequestTimestamp;
const triggerProcess = async () => {
console.log("Triggering process");
// Don't run the process if something is currently processing.
// "triggerProcess" will be called again because this item is still in the
// queue
if (this.currentlyProcessing) {
return;
}
this.lastRequestTimestampMap[processName] = Date.now();
this.lastRequestTimestampMap[ANY_KEY] = Date.now();
// Remove the process from the queue
const processToTrigger = this.processQueue.shift();
if (processToTrigger) {
this.currentlyProcessing = processToTrigger;
try {
console.log("Before process trigger");
console.log("The current:", this.currentlyProcessing);
const returnValue = await processToTrigger.perform(
...processToTrigger.args,
);
console.log("After process trigger");
if (processToTrigger.after) {
processToTrigger.after(returnValue);
}
processToTrigger.awaitingResolutions.forEach((callback) => {
console.log("Resolved");
callback(returnValue);
});
} catch (err) {
@ -143,8 +155,10 @@ export class RequestBatcher {
};
if (timeSinceLastTrigger < this.batchMillis) {
console.log("Waiting for the future");
setTimeout(triggerProcess, this.batchMillis - timeSinceLastTrigger);
} else {
console.log("Doing it now");
triggerProcess();
}
}
@ -158,6 +172,7 @@ export class RequestBatcher {
options: WaitingProcessOptions<Args, ReturnType>,
): Promise<ReturnType> {
return new Promise((resolve, reject) => {
console.log("Queuing process");
const shouldAwait = options.modifyQueue(
this.processQueue,
this.currentlyProcessing,

@ -134,7 +134,7 @@ async function testRequestLoads<ReturnVal>(
return returnVal;
}
describe("SolidLdoDataset", () => {
describe("Integration", () => {
let app: App;
let authFetch: typeof fetch;
let fetchMock: jest.Mock<

Loading…
Cancel
Save