Skip to content

Commit

Permalink
perf: various updates
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret committed Dec 26, 2023
1 parent ec15e8c commit 716396c
Show file tree
Hide file tree
Showing 11 changed files with 464 additions and 149 deletions.
8 changes: 4 additions & 4 deletions dprint.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"**/*-lock.json"
],
"plugins": [
"https://plugins.dprint.dev/typescript-0.88.3.wasm",
"https://plugins.dprint.dev/json-0.19.0.wasm",
"https://plugins.dprint.dev/markdown-0.16.2.wasm",
"https://plugins.dprint.dev/prettier-0.27.0.json@3557a62b4507c55a47d8cde0683195b14d13c41dda66d0f0b0e111aed107e2fe"
"https://plugins.dprint.dev/typescript-0.88.7.wasm",
"https://plugins.dprint.dev/json-0.19.1.wasm",
"https://plugins.dprint.dev/markdown-0.16.3.wasm",
"https://plugins.dprint.dev/prettier-0.31.0.json@8808616145fecc35574b79e78620f7fb241afba445201e64042dc78e01a1022b"
]
}
17 changes: 16 additions & 1 deletion handleRequest.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { assertEquals } from "./deps.test.ts";
import { handleRequest } from "./handleRequest.ts";
import { createRequestHandler } from "./handleRequest.ts";
import { RealClock } from "./utils/clock.ts";

const connInfo: Deno.ServeHandlerInfo = {
remoteAddr: {
transport: "tcp",
hostname: "127.0.0.1",
port: 80,
},
};

Deno.test("should get info.json", async () => {
const { handleRequest } = createRequestHandler(new RealClock());
const response = await handleRequest(
new Request("https://plugins.dprint.dev/info.json"),
connInfo,
);
assertEquals(response.headers.get("content-type"), "application/json; charset=utf-8");
const data = await response.json();
Expand All @@ -15,17 +26,21 @@ Deno.test("should get info.json", async () => {
});

Deno.test("should get cli.json", async () => {
const { handleRequest } = createRequestHandler(new RealClock());
const response = await handleRequest(
new Request("https://plugins.dprint.dev/cli.json"),
connInfo,
);
assertEquals(response.headers.get("content-type"), "application/json; charset=utf-8");
const data = await response.json();
assertEquals(typeof data.version, "string");
});

async function getRedirectUrl(url: string) {
const { handleRequest } = createRequestHandler(new RealClock());
const response = await handleRequest(
new Request(url),
connInfo,
);
assertEquals(response.status, 302);
return response.headers.get("location")!;
Expand Down
200 changes: 106 additions & 94 deletions handleRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { renderHome } from "./home.tsx";
import oldMappings from "./old_redirects.json" assert { type: "json" };
import { tryResolveLatestJson, tryResolvePluginUrl, tryResolveSchemaUrl } from "./plugins.ts";
import { readInfoFile } from "./readInfoFile.ts";
import { fetchCached, getCliInfo } from "./utils/mod.ts";
import { Clock } from "./utils/clock.ts";
import { createFetchCacher, getCliInfo } from "./utils/mod.ts";

const contentTypes = {
css: "text/css; charset=utf-8",
Expand All @@ -12,73 +13,112 @@ const contentTypes = {
wasm: "application/wasm",
};

export async function handleRequest(request: Request) {
const url = new URL(request.url);
const newUrl = await resolvePluginOrSchemaUrl(url);
if (newUrl != null) {
const contentType = newUrl.endsWith(".json")
? contentTypes.json
: newUrl.endsWith(".wasm")
? contentTypes.wasm
: contentTypes.plain;
return handleConditionalRedirectRequest({
request,
url: newUrl,
contentType,
});
}

const userLatestInfo = await tryResolveLatestJson(url);
if (userLatestInfo != null) {
if (userLatestInfo === 404) {
return new Response("Not Found", {
status: 404,
});
export function createRequestHandler(clock: Clock) {
const { fetchCached } = createFetchCacher(clock);
return {
async handleRequest(request: Request, info: Deno.ServeHandlerInfo) {
const url = new URL(request.url);
const newUrl = await resolvePluginOrSchemaUrl(url);
if (newUrl != null) {
const contentType = newUrl.endsWith(".json")
? contentTypes.json
: newUrl.endsWith(".wasm")
? contentTypes.wasm
: contentTypes.plain;
return handleConditionalRedirectRequest({
request,
url: newUrl,
contentType,
hostname: info.remoteAddr.hostname,
});
}

const userLatestInfo = await tryResolveLatestJson(url);
if (userLatestInfo != null) {
if (userLatestInfo === 404) {
return new Response("Not Found", {
status: 404,
});
} else {
return createJsonResponse(JSON.stringify(userLatestInfo, undefined, 2), request);
}
}

if (url.pathname.startsWith("/info.json")) {
const infoFileData = await readInfoFile();
return createJsonResponse(JSON.stringify(infoFileData, null, 2), request);
}

if (url.pathname.startsWith("/cli.json")) {
const cliInfo = await getCliInfo();
return createJsonResponse(JSON.stringify(cliInfo, null, 2), request);
}

if (url.pathname === "/style.css") {
return Deno.readTextFile("./style.css").then(text =>
new Response(text, {
headers: {
"content-type": "text/css; charset=utf-8",
},
status: 200,
})
);
}

if (url.pathname === "/") {
return renderHome().then(home =>
new Response(home, {
headers: {
"content-type": contentTypes.html,
},
status: 200,
})
).catch(err =>
new Response(`${err.toString?.() ?? err}`, {
headers: {
"content-type": contentTypes.plain,
},
status: 500,
})
);
}

return create404Response();
},
};

// This is done to allow the playground to access these files
function handleConditionalRedirectRequest(params: {
request: Request;
url: string;
contentType: string;
hostname: string;
}) {
if (shouldDirectlyServeFile(params.request)) {
return fetchCached(params)
.then(result => {
if (result.kind === "error") {
return result.response;
}

return new Response(result.body, {
headers: {
"content-type": params.contentType,
// allow the playground to download this
"Access-Control-Allow-Origin": getAccessControlAllowOrigin(params.request),
},
status: 200,
});
}).catch(err => {
console.error(err);
return new Response("Internal Server Error", {
status: 500,
});
});
} else {
return createJsonResponse(JSON.stringify(userLatestInfo, undefined, 2), request);
return createRedirectResponse(params.url);
}
}

if (url.pathname.startsWith("/info.json")) {
const infoFileData = await readInfoFile();
return createJsonResponse(JSON.stringify(infoFileData, null, 2), request);
}

if (url.pathname.startsWith("/cli.json")) {
const cliInfo = await getCliInfo();
return createJsonResponse(JSON.stringify(cliInfo, null, 2), request);
}

if (url.pathname === "/style.css") {
return Deno.readTextFile("./style.css").then(text =>
new Response(text, {
headers: {
"content-type": "text/css; charset=utf-8",
},
status: 200,
})
);
}

if (url.pathname === "/") {
return renderHome().then(home =>
new Response(home, {
headers: {
"content-type": contentTypes.html,
},
status: 200,
})
).catch(err =>
new Response(`${err.toString?.() ?? err}`, {
headers: {
"content-type": contentTypes.plain,
},
status: 500,
})
);
}

return create404Response();
}

async function resolvePluginOrSchemaUrl(url: URL) {
Expand All @@ -87,41 +127,13 @@ async function resolvePluginOrSchemaUrl(url: URL) {
?? await tryResolveSchemaUrl(url);
}

// This is done to allow the playground to access these files
function handleConditionalRedirectRequest(params: { request: Request; url: string; contentType: string }) {
if (shouldDirectlyServeFile(params.request)) {
return fetchCached(params.url)
.then(result => {
if (result.kind === "error") {
return result.response;
}

return new Response(result.body, {
headers: {
"content-type": params.contentType,
// allow the playground to download this
"Access-Control-Allow-Origin": getAccessControlAllowOrigin(params.request),
},
status: 200,
});
}).catch(err => {
console.error(err);
return new Response("Internal Server Error", {
status: 500,
});
});
} else {
return createRedirectResponse(params.url);
}
}

function getAccessControlAllowOrigin(request: Request) {
const origin = request.headers.get("origin");
return origin != null && new URL(origin).hostname === "localhost" ? origin : "https://dprint.dev";
}

function shouldDirectlyServeFile(request: Request) {
// directly serve for when Deno makes a request
// directly serve for when Deno makes a request in order to fix the content type
if (request.headers.get("user-agent")?.startsWith("Deno/")) {
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion import_map.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"imports": {
"preact": "https://esm.sh/preact@10.15.1?pin=v135",
"preact/": "https://esm.sh/preact@10.15.1?pin=v135/",
"preact/": "https://esm.sh/preact@10.15.1&pin=v135/",
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@6.1.0?pin=v135"
}
}
7 changes: 5 additions & 2 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { handleRequest } from "./handleRequest.ts";
import { createRequestHandler } from "./handleRequest.ts";
import { RealClock } from "./utils/clock.ts";

Deno.serve((request) => handleRequest(request));
const { handleRequest } = createRequestHandler(new RealClock());

Deno.serve((request, info) => handleRequest(request, info));
Loading

0 comments on commit 716396c

Please # to comment.